发布时间:2023-01-30 09:00
目录
零、前言
一、字符串操作函数(长度不受限)
1.1 strlen——求字符串长度
1.2 strcpy——字符串拷贝
1.3 strcat——字符串追加
1.4 strcmp——字符串比较
二、字符串操作函数(长度受限)
2.1 strncpy
2.2 strncat
2.3 strncmp
‘a’——字符 "abcdef"——字符串
C语言中并没有字符串类型,但有很多相关函数。
字符串"abcdef"其实储存的是a b c d e f \0 ,而对于strlen函数求其长度,则是从a开始数,一直数到\0停止,则可得到"abcdef"这个字符串长度为6。
#include
#include
int main()
{
char arr[] = "abcdef";
int len = strlen(arr);
printf("%d", len);
}
这样输出的结果为6。
在MSDN上对strlen的介绍如下:
但如果你是这样初始化字符串的:char arr[] = {'a','b','c','d','e','f'};那么就会得到一个随机值。因为这样定义的话字符串并不以'\0'结束。如果是char arr[] = {'a','b','c','d','e','f','\0'};或者char arr[10] = {'a','b','c','d','e','f'};则可返回6。
【小结strlen注意事项】:
1.strlen返回的是以'\0'为结束的字符串的长度,即他计算的是'\0'前的字符个数!
2.strlen的返回值为size_t,是无符号的。所以就算strlen("abc")-strlen("abcdefg")结果也是大于0的。可以用>/<直接比较,或强制转换为别的类型如int的方法来解决这一问题。
【strlen的模拟实现】:
#include
#include
//1.计数器的方法
size_t my_strlen1(const char* str) //用const保护指针所指内容使其更安全
{
int count = 0;
assert(str != NULL); //确保str不为空指针
while (*str != '\0') //没到\0就加一
{
count++;
str++;
}
return count;
}
//2.递归的方法
size_t my_strlen2(const char* str)
{
assert(str != NULL);
if (*str == '\0')
return 0;
else
return 1 + my_strlen2(str+1);
}
//3.指针-指针的方法
size_t my_strlen3(char* str)
{
assert(str != NULL);
char* p = str;
while (*p != '\0')
p++;
return p - str;
}
int main()
{
char arr[] = "abcdef";
printf("%d %d %d", my_strlen1(arr), my_strlen2(arr), my_strlen3(arr));
return 0;
}
#include
#include
int main()
{
char arr1[20] = {0};
char arr2[] = "abcdef";
strcpy(arr1, arr2);
return 0;
}
这样就可以让arr1中复制为arr2的内容,即此时arr1的内容为"abcdef"(注意是包括\0的)会拷贝\0并且拷贝过\0后停下来。所以arr2即源字符串里必须有\0!如果没有,程序会崩溃。
【小结strcpy注意事项】:
1.源字符串必须有\0
2.会拷贝\0过去
3.目标空间必须足够大,以确保能存放源字符串。(不够大程序会崩溃报错,但能拷贝过去。但作为负责的程序员是不能让这种事发生滴!)
4.目标空间必须可修改
如 char* arr1 = "qwertyuiop";则arr1为常量字符串,常量是不可修改的!所以此时不能把东西拷贝到arr1里。
【strcpy的模拟实现】:
char* my_strcpy(char* dest, const char* src)
{
assert(src && dest); //同时assert了src和dest都不是NULL
char* ret = dest;
while (*dest++ = *src++) //将src赋值过去,不是\0就继续,这样可以一口气把\0也拷贝过去,妙!
{
;
}
return ret;
}
int main()
{
char arr1[20] = { 0 };
char arr2[] = "abcdef";
printf("%s", my_strcpy(arr1, arr2));
return 0;
}
(补充:strcpy返回类型的设计是为了链式访问~)
int main()
{
char arr1[20] = "abc";
char arr2[] = "defg";
strcat(arr1, arr2);
return 0;
}
这个代码即可实现defg追加到abc后面。从目标字符串的\0向后追加,追加到源字符串的\0,并且把\0也追加过来。
【小结strcat注意事项】:
1.源字符串和目标字符串都必须有\0
2.目标空间必须足够大,能容纳下源字符串的内容
3.目标空间必须可修改
【strcat的模拟实现】:
char* my_strcat(char* dest, const char* src)
{
assert(dest && src);
char* ret = dest;
//找目标空间中的\0
while (*dest)
{
dest++;
}
//拷贝
while(*dest++ = *src++)
{
;
}
return ret;
}
int main()
{
char arr1[20] = "abc";
char arr2[] = "def";
printf("%s", my_strcat(arr1, arr2));
return 0;
}
(补充:如果用我模拟的strcat自己给自己追加即my_strcat(arr1,arr1);则会死循环。但库里的可能可以正常。)
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abq";
printf("%d", strcmp(arr1, arr2));
return 0;
}
不是比较字符串的长度,而是比较字符串中对应位置上的字符的大小。如果相同,就比较下一对,直到不同或都遇到\0。
【strcmp的模拟实现】:
int my_strcmp(const char* arr1, const char* arr2)
{
assert(arr1 && arr2);
while(*arr1 == *arr2)
{
if (*arr1 == '\0')
{
return 0;
}
arr1++;
arr2++;
}
if (*arr1 > *arr2)
return 1;
else
return -1;
}
int main()
{
char arr1[20] = "abc";
char arr2[] = "abq";
printf("%d", my_strcmp(arr1, arr2));
return 0;
}
strcpy strcat strcmp——都是长度不受限制的字符串函数
strncpy strncat strncmp——长度受限制的字符串函数(相对安全)
比strcpy多了一个参数,代表要拷贝几个字符。
例如:
int main()
{
char arr1[] = "abcdef";
char arr2[] = "qwertyuiop";
strncpy(arr1, arr2, 3);
printf("%s\n", arr1);
return 0;
}
此时输出即为qwedef。
如果源字符串长度小于需要拷贝的长度:
int main()
{
char arr1[] = "abcdef";
char arr2[] = "qwe";
strncpy(arr1, arr2, 5);
printf("%s\n", arr1);
return 0;
}
结果为qwe,因为超出的部分会用\0填充。但尽量不要这样写。
比strcat多了一个参数,代表要追加几个字符。
例如:
int main()
{
char arr1[20] = "abcdef";
char arr2[] = "qwertyuiop";
strncat(arr1, arr2, 5);
printf("%s\n", arr1);
return 0;
}
输出为abcdefqwert。\0也会被追加过去并不算在追加的个数之内。如果源字符串长度小于需要追加的长度,则会补充\0。
比strcmp多了一个参数,代表要比较几个字符。
例如:
int main()
{
char arr1[20] = "abcdef";
char arr2[] = "qwertyuiop";
int ret = strncmp(arr1, arr2, 5);
printf("%d\n", ret);
return 0;
}
应该输出一个小于零的数。
(补充:如果是单纯的字符串大小于号的比较 if("abcdef">"abc") 此时比较的是地址)
C语言常见库函数详解——【字符/字符串函数及内存操作函数】(一)的部分就到这里啦~更多精彩内容可见下一篇博客:C语言常见库函数详解——【字符/字符串函数及内存操作函数】(二)!欢迎大家多多交流!