有关strcat的补充:不能自己追加自己
int main() { char arr[] = "hello"; strcat(arr, arr); printf("%sn", arr); return 0; }
为什么strcat不能自己追加自己?
就上述例子来讲, strcat库函数实现的原理是先找到字符串hello末尾的'',然后再将h 代替'',接着继续追加,但是追加的结束标志是'',而源字符串的''已经被替换了,所以程序会崩溃
接下来继续介绍其他的库函数:
1.strcmp(字符串比较)
标准规定:
第一个字符串大于第二个字符串,返回大于0的数字
第一个字符串等于第二个字符串,返回0
第一个字符串小于第二个字符串,返回小于0的数字
1)错误示范
int main() { char* p = "abc"; char* q = "defgh"; if (p > q) { printf(">n"); } else { printf("<=n"); } return 0; }
p中存储的是字符串"abc"中a的地址
q中存储的是字符串"defgh"中d的地址
两个指针比较大小,由于"abc"先创建,在高地址,而"defgh"后创建,在低地址,会打印出'>',但实际上应该是'<'
所以比较字符串大小这样写是错误的
既然刚才那么写不行,那么这样写对吗?
int main() { if ("abc" > "defgh") { } return 0; }
本质上也是拿'a'的地址与'd'的地址进行比较,是错误的,不行
2)strcmp的使用
int main() { char* p = "abc"; char* q = "abbdef"; int ret = strcmp(p, q); if (ret > 0) { printf("p > qn"); } else if (ret < 0) { printf("p < qn"); } else { printf("p == qn"); } return 0; }
有关 strcmp的一个易错点:
strcmp比较的是两个字符串的大小,并不是长度。比如"abc"和"abbdef"比较,先是a与a比较,一样;再b与b比较,一样;再c与b比较,c的ASCII码值比b的ASCII码值大(c再ASCII表中的排序在b后面),所以c > b,所以"abc" > "abbdef"。(一个字符一个字符进行比较,''为结束标志,并不是字符串长就大)
3)my_strcmp的实现
int my_strcmp(const char* s1, const char* s2)//const修饰,更加安全 { assert(s1 && s2);//断言 while (*s1 == *s2)//两字符相等进入循环 { if (*s1 == '')//如果两字符串到''都相等,返回0 { return 0; } s1++; s2++; } if (*s1 > *s2)//如果前字符大于后字符,返回1 { return 1; } else//如果前字符小于后字符,返回-1 { return -1; } } int main() { char* p = "abb"; char* q = "abb"; int ret = my_strcmp(p, q); if (ret > 0) { printf("p > qn"); } else if (ret < 0) { printf("p < qn"); } else { printf("p == qn"); } return 0; }
更简洁的代码实现my_strcmp
int my_strcmp(const char* s1, const char* s2)//const修饰,更加安全 { assert(s1 && s2);//断言 while (*s1 == *s2)//两字符相等进入循环 { if (*s1 == '')//如果两字符串到''都相等,返回0 { return 0; } s1++; s2++; } return (*s1 - *s2);//遇到两字符不相等时,返回两字符差值 } int main() { char* p = "abb"; char* q = "abd"; int ret = my_strcmp(p, q); if (ret > 0) { printf("p > qn"); } else if (ret < 0) { printf("p < qn"); } else { printf("p == qn"); } return 0; }
2. strncpy strncat strncmp
strcpy strcat strcmp都是长度不受限制的字符串函数
strncpy strncat strncmp都是长度受限制的字符串函数
strncpy strncat strncmp本质上和strcpy strcat strcmp类似,只是多了一个参数,功能几乎是一样的
1)strncpy
int main() { char arr1[20] = "abcde"; char arr2[] = "bribe"; strncpy(arr1, arr2, 3); printf("%sn", arr1); return 0; }
char * __cdecl strncpy ( char * dest, const char * source, size_t count ) { char *start = dest; while (count && (*dest++ = *source++) != '') count--; if (count) while (--count) *dest++ = ''; return(start); }
上面是strncpy的源码
2)strncat
int main() { char arr1[20] = "abcde"; char arr2[] = "bribe"; strncat(arr1, arr2, 3); printf("%sn", arr1); return 0; }
char * __cdecl strncat ( char * front, const char * back, size_t count ) { char *start = front; while (*front++) ; front--; while (count--) if ((*front++ = *back++) == 0) return(start); *front = ''; return(start); }
上面是strncat的源码
3)strncmp
int main() { char arr1[20] = "abcde"; char arr2[] = "bribe"; int ret = strncmp(arr1, arr2, 3); printf("%dn", ret); return 0; }
在这三个函数中,如果最后一个参数大于源字符串的长度,会把多余的部分用''代替继续执行
int __cdecl strncmp ( const char *first, const char *last, size_t count ) { size_t x = 0; if (!count) { return 0; } if( count >= 4 ) { for (; x < count-4; x+=4) { first+=4; last +=4; if (*(first-4) == 0 || *(first-4) != *(last-4)) { return(*(unsigned char *)(first-4) - *(unsigned char *)(last-4)); } if (*(first-3) == 0 || *(first-3) != *(last-3)) { return(*(unsigned char *)(first-3) - *(unsigned char *)(last-3)); } if (*(first-2) == 0 || *(first-2) != *(last-2)) { return(*(unsigned char *)(first-2) - *(unsigned char *)(last-2)); } if (*(first-1) == 0 || *(first-1) != *(last-1)) { return(*(unsigned char *)(first-1) - *(unsigned char *)(last-1)); } } } for (; x < count; x++) { if (*first == 0 || *first != *last) { return(*(unsigned char *)first - *(unsigned char *)last); } first+=1; last+=1; } return 0; }
上面是 strncmp的源码
未完待续
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)