扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
求字符串长度
size_t strlen ( const char * str );
#includeint main()
{int len = strlen("abcdef");
printf("%d\n", len);
return 0;
}//6
结果
上一篇写strlen()函数的模拟实现中有3种方法:大龄失业学生转码日记:2022-12-02(strlen函数)
1、计数器的方法;
2、递归的方法;
3、指针-指针的方法
#include
#include//因为求的是字符串长度,不会改变str所指向字符串的内容,所以加const修饰,
//即使str所指向的内容想要被修改也没有机会了。
int my_strlen(const char* str)
{//断言:保证指针的有效性:
assert(str != NULL);
//用计数器的方法实现:
int count = 0;
while (*str != '\0')//或while(*str)都可以
{count++;
str++;
}
return count;
}
int main()
{int len = my_strlen("abcdef");
//表面传的是字符串,实际传的是字符串首字符地址。
printf("%d\n", len);
return 0;
}
结果
sizeof——是操作符,计算大小。sizeof计算的结果返回的类型是size_t;size_t 是专门为sizeof的返回值设计的。
size_t——其实是unsigned int类型,只表示正数。
strlen()函数返回的是无符号数,两个无符号的数相减得到的也是无符号的数,比如下述代码中会把-3当做无符号的数处理,是一个非常大的正数而会引入bug。
#include#includeint main()
{if (strlen("abc") - strlen("abcdef") >0)
{printf(">");
}
else
{printf("<=");
}
return 0;
}
结果
strlen()的返回值可以写成int类型,size_t类型或unsigned_int类型都可以。
上述代码强制类型转换为int可以得出“<=”:
#include#includeint main()
{if ((int)strlen("abc") - (int)strlen("abcdef") >0)
{printf(">");
}
else
{printf("<=");
}
return 0;
}
结果
使用库函数时需要包含头文件,不包含会有bug。
使用strlen()函数时:
字符串以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包
含 ‘\0’ )。
参数指向的字符串必须要以 ‘\0’ 结束。
函数的返回值为size_t,是无符号的。
strcpy()函数用来拷贝字符串,会把源字符串内容拷贝到目标空间中,\0也会被拷贝过去。
char* strcpy(char * destination, const char * source );
把arr1的内容拷贝放到arr2中
#include#includeint main()
{char arr1[] = "abcdef";
char arr2[20] = {0 };
strcpy(arr2, arr1);
printf("%s\n", arr2);
return 0;
}
结果
注意:在使用strcpy()函数时:
源字符串必须以 ‘\0’ 结束。
会将源字符串中的 ‘\0’ 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串,防止造成越界访问而使程序崩溃。
目标空间必须可变。
#include#includeint main()
{char arr1[] = {'a','b','c','d','e','f' };
char arr2[20] = "XXXXXXXX";
strcpy(arr2, arr1);
printf("%s\n", arr2);
return 0;
}
程序会崩溃,拷贝内容混乱
可以改为如下写法
#include#includeint main()
{char arr1[] = {'a','b','c','d','e','f','\0' };
char arr2[20] = "XXXXXXXX";
strcpy(arr2, arr1);
printf("%s\n", arr2);
return 0;
}
结果
strcpy()函数可以将源字符串内容拷贝到已有数据的数组中。
注意:遇到\0的时候,打印也结束了。所以即使目标空间在\0(这里的\0是从源数据中拷贝的)后面还有数据也不能打印了。
#include#includeint main()
{char arr1[] = {'a','b','c','\0','d','e','f' };
char arr2[20] = "XXXXXXXX";
strcpy(arr2, arr1);
printf("%s\n", arr2);
return 0;
}
结果
strcpy()函数的模拟实现:
#include#include
//把源头数据拷贝到目标空间中,整个过程中,源数据是不需要发生变化的,目标空间需要变化
//所以在源数据前面可以用const修饰限定,保护源头数据。
char* my_strcpy(char* dest, const char* src)
{char* ret = dest;
assert(dest && src);
while (*src)
{*dest = *src;
dest++;
src++;
}
*dest = *src;//拷贝\0
return ret;
}
int main()
{char arr1[] = {'a','b','c','d','e','f','\0' };
char arr2[] = "xxxxxxxx";
my_strcpy(arr2, arr1);
printf("%s\n", arr2);
return 0;
}//abcdef
结果
把源字符串内容追加到目标字符串的后面。
char * strcat ( char * destination, const char * source );
strcpy()函数是拷贝,覆盖原来的数据。
strcat()函数是把源字符串内容追加到目标字符串的后面。
#includeint main()
{char arr1[30] = "hello";
char arr2[] = "world";
//把arr2中的数据追加到arr1中
strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
结果
原理:arr2找到arr1的‘\0’,把‘\0’覆盖掉然后拷贝arr2的内容。这里arr2是源字符串,‘\0’不会拷贝。
#include#includeint main()
{char arr1[30] = "hello";
char arr2[] = {'w','o','r','l','d' };
strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
源字符串并没有以’\0’结束,程序崩溃
改为如下
#include#includeint main()
{char arr1[30] = {'h','e','l','l','o'};
char arr2[] = "world";
strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
结果
用来比较两个字符串。比较的是对应位置上的字符的大小——比较的是字符的ASCII码值。a、b、c、d……按照顺序ASCII码值依次增大。
int strcmp ( const char * str1, const char * str2 );
标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字;
第一个字符串等于第二个字符串,则返回0;
第一个字符串小于第二个字符串,则返回小于0的数字。
#include#includeint main()
{char arr1[] = "abcdef";
char arr2[] = "bbq";
int ret = strcmp(arr1, arr2);
printf("%d\n", ret);
return 0;
}
结果
比的不是长度。
“abcdef”;
“bbq”;
这两个字符串对应的第一个字符比,a“abcdef”;
“abq”;
这两个字符串对应的第一个字符相等,就比较第二个对应的字符,第二个字符相等就比较第三对……直到比较双方的‘\0’。
#include#includeint main()
{char arr1[] = "bbq";
char arr2[] = "bbq";
int ret = strcmp(arr1, arr2);
printf("%d\n", ret);
return 0;
}
#include#includeint main()
{char arr1[] = "qbq";
char arr2[] = "bbq";
int ret = strcmp(arr1, arr2);
printf("%d\n", ret);
return 0;
}
结果
模拟实现strcmp()函数:
#include#include
int my_strcmp(const char* str1, const char* str2)//因为只访问内容不会修改这两个字符串内容所以可以加const保护
{//因为后面有对这两个指针解引用操作,所以需要断言是否是空指针
assert(str1 && str2);
while (*str1 == *str2)
{if (*str1 == '\0')
{ return 0;
}
str1++;
str2++;
}
if (*str1 >*str2)
{return 1;
}
else
{return -1;
}
}
int main()
{char arr1[] = "abc";
char arr2[] = "abcd";
printf("%d\n", my_strcmp(arr1, arr2));
return 0;
}
结果
‘\0’的ASCII码值是0。
注意:两个字符串是不能相减的,两个字符串不能用等号来判断是否相等,更不能相减。
if ("abq" == "abc")
错误代码,"abq"表达式产生的是它的a的地址(首字符的地址);
"abc"表达式产生的是它的a的地址;
这两个地址一定不相等,所以不能用等号比。
if("abc" - "abq")
意思是这两个地址相减比较的是地址,就不是比较的两个字符串的内容是否相等了;
所以两个字符串不能相加,不能相减。
如果两个字符串是常量字符串,那么二者的地址是相同的;
但是如果是两个字符串数组,即使字符串内容相同地址也不会相同,因为是两个完全不同的空间。
总结:
1 strcpy()函数在拷贝的时候,直到把源字符串中的\0拷贝完之后才停止拷贝,即拷贝到\0。
2 strcat()函数在追加的时候,也只在乎\0的问题,追加到\0。
3 strcmp()函数比较字符串的时候不相等就结束,相等就比较到\0。
4 这三个函数在拷贝的时候并没有考虑拷贝的长度,一直到\0,所以这三个函数均是长度不受限制的字符串函数,与字符串的长度没有关系。这三者头文件均是
拷贝num个字符从源字符串到目标空间。
如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
char * strncpy ( char * destination, const char * source, size_t num );
#include#includeint main()
{char arr1[] = "xxxxxxxxxxxxx";
char arr2[] = "hello world";
//若把arr2中的hello这5个字符拷贝到arr1中:
strncpy(arr1, arr2, 5);//只是把前5个hello拷贝过去
printf("%s\n", arr1);
return 0;
}
结果
如果长度不够,会主动放上’\0’
#include#includeint main()
{char arr1[] = "xxxxxxxxxxxxx";
char arr2[] = "he";
strncpy(arr1, arr2, 5);
printf("%s\n", arr1);
return 0;
}
结果
如果长度不够,会主动放上’\0’
strncpy()函数相对较灵活,更可控、相对安全。
把源字符串的num个字符追加到目标空间中。
char * strncat ( char * destination, const char * source, size_t num );
#include#includeint main()
{char arr1[20] = "hello";
char arr2[] = "world";
//把arr2中的world这5个字符追加到arr1中
strncat(arr1, arr2, 5);
printf("%s\n", arr1);
return 0;
}
结果
#include#includeint main()
{char arr1[20] = "hello";
char arr2[] = "world";
//把arr2中的world中的3个字符追加到arr1中
strncat(arr1, arr2, 3);
printf("%s\n", arr1);
return 0;
}
结果
#include#includeint main()
{char arr1[20] = "hello\0";
char arr2[] = "world";
//把arr2中的world中的3个字符追加到arr1中
strncat(arr1, arr2, 3);
printf("%s\n", arr1);
return 0;
}
结果
#include#includeint main()
{char arr1[20] = "hello\0xxxxxxx";
char arr2[] = "world";
//把arr2中的world中的3个字符追加到arr1中
strncat(arr1, arr2, 3);
printf("%s\n", arr1);
return 0;
}
结果
strncat追加后还是字符串,所以会在追加指定的几个字符后主动自己加上\0,所以追加完就停止打印。
#include#includeint main()
{char arr1[20] = "hello\0xxxxxxx";
char arr2[] = "world";
//把arr2中的world这5个字符追加到arr1中
strncat(arr1, arr2, 5);
printf("%s\n", arr1);
return 0;
}
结果
#include#includeint main()
{char arr1[20] = "helloxxxxxxx";
char arr2[] = "world";
strncat(arr1, arr2, 7);
printf("%s\n", arr1);
return 0;
}
结果
#include#includeint main()
{char arr1[20] = "helloxxxxxxx";
char arr2[] = "world";
//把arr2中的world中3个字符追加到arr1中
strncat(arr1, arr2, 3);
printf("%s\n", arr1);
return 0;
}
结果
注意:
1、遇到\0;
2、追加的数字小于源字符串长度时,追加完要追加的字符后就不追加了。
比较num个字符串大小。
int strncmp ( const char * str1, const char * str2, size_t num );
#include#includeint main()
{char arr1[] = "abcdef";
char arr2[] = "abcqqqqqq";
int ret = strncmp(arr1, arr2, 3);
printf("%d\n", ret);
return 0;
}
结果
#include#includeint main()
{char arr1[] = "abcdef";
char arr2[] = "abcqqqqqq";
int ret = strncmp(arr1, arr2, 4);
printf("%d\n", ret);
return 0;
}
结果
#include#includeint main()
{char arr1[] = "abcwef";
char arr2[] = "abcqqqqqq";
int ret = strncmp(arr1, arr2, 4);
printf("%d\n", ret);
return 0;
}
结果
总结:
strncpy()函数 —— 拷贝
strncat ()函数 —— 追加
strncmp()函数 —— 比较
这三者是长度受限制的字符串函数,头文件均是
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流