一:strlen
size_t strlen ( const char * str );
注意事项:
字符串以'\0'作为结束标志,strlen函数返回值是在字符串中'\0'前面出现的字符个数(不包含'\0')
参数是一个字符指针变量
参数指向的字符串必须要以'\0'结束,否则计算出的长度是随机值
注意函数的返回值为size_t,是无符号的
因为返回值是size_t,所以就要避免出现下面这样的代码:strlen("abc") - strlen("abcde"),strlen("abc")算出的结果是3, strlen("abcde")算出的结果是5,可能想着3-5得到-2,实际上并不是这样的,这里算出的3和5都是无符号整型,算出的-2也是一个无符号整型,-2在内存中以补码的形式存储,从无符号整型的视角看去,这串补码就表示一个很大的正数。
模拟实现:
//常规实现 int my_strlen1(const char* arr) { assert(arr != NULL); int count = 0; while (*arr) { count++; arr++; } return count; } //递归实现 int my_strlen2(const char* arr) { assert(arr!=NULL); if (*arr == '\0') { return 0; } else { return 1 + my_strlen2(arr + 1); } } //指针减指针实现 int my_strlen3(const char* arr) { assert(arr != NULL); const char* start = arr; while (*arr) { arr++; } return arr - start; } int main() { char arr[] = "abcdef"; int len = my_strlen3(arr); printf("%d\n", len); return 0; }
二:strcpy
strcpy:字符串拷贝函数,把源字符串拷贝到目标空间
char * strcpy ( char * destination, const char * source );
注意事项:
函数有两个参数,其中source指向待拷贝的字符串,也叫做源字符串,destination是目标空间的地址
源字符串必须以’\0’结束
会把源字符串中的 ‘\0’ 也拷贝到目标空间
目标空间必须足够大,以确保能存放源字符串,否则会出现非法访问
目标空间必须可变,例如把源字符串拷贝到一个字符串常量里面是不可取的
模拟实现:
char* my_strcpy(char* dest, const char* src) { assert(dest && src); char* ret = dest; while (*dest++ = *src++) { ; } return ret; } int main() { char arr1[20] = { 0 }; char arr2[] = "hello world"; my_strcpy(arr1, arr2); printf("%s\n", arr1); return 0; }
三:strcat
strcat:字符串追加函数,将源字符串追加到目标字符串后面,目标中的终止字符’\0’会被源字符串的第一个字符覆盖
char * strcat ( char * destination, const char * source );
注意事项:
函数有两个参数,其中source指向要追加的字符串,也叫做源字符串,destination是目标空间的地址
目标空间中必须要有'\0',作为追加的起始地址
源字符串中也必须要有'\0'作为追加的结束标志
目标空间必须足够大,能容纳下源字符串的内容
目标空间必须可修改
自己给自己追加会陷入死循环
模拟实现:
char* my_strcat(char* dest, const char* src) { assert(dest && src); char* ret = dest; //找目标空间的'\0' while (*dest != '\0') { dest++; } //追加 while (*dest++ = *src++) { ; } return ret; } int main() { char arr1[20] = "hello "; char arr2[] = "world"; my_strcat(arr1, arr2); printf("%s\n", arr1); return 0; }
四:strcmp
strcmp:字符串比较函数
int strcmp ( const char * str1, const char * str2 );
注意事项:
- 这里比较的不是两个字符串的长度,而是对应位置上的ASCII值
- 第一个字符串大于第二个字符串,则返回大于0的数字
- 第一个字符串等于第二个字符串,则返回0
- 第一个字符串小于第二个字符串,则返回小于0的数字
模拟实现:
int my_strcmp(const char* str1, const char* str2) { assert(str1 && str2); while (*str1 == *str2)//如果相等就进去,两个指针加加,但是可能会出现两个字符串相等的情况,两个指针都指向'\0',此时比较就结束了 { if (*str1 == '\0') { return 0; } str1++; str2++; } if (*str1 > *str2) { return 1; } else { return -1; } } int main() { char arr1[] = "abq"; char arr2[] = "abq"; int ret=my_strcmp(arr1, arr2); printf("%d\n", ret); return 0; }
五:strncpy
strncpy:长度受限的字符串拷贝函数
char * strncpy ( char * destination, const char * source, size_t num );
注意事项:
- 拷贝num个字符从源字符串到目标空间。
- 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
模拟实现:
char* my_strncpy(char* dest, const char* src, int num) { assert(dest && src); char* ret = dest; while (num) { if (*src == '\0')//此时说明src指针已经指向了待拷贝字符串的结束标志'\0'处,src指针就不用再++了 { *dest = '\0'; dest++; } else { *dest = *src; dest++; src++; } num--; } return ret; } int main() { char arr1[20] = "xxxxxxxxxxxxxxxxxxx"; my_strncpy(arr1, "abcdef", 10); printf("%s\n", arr1); return 0; }
六:strncat
strncat:长度受限的字符串追加函数
char * strncat ( char * destination, const char * source, size_t num );
注意事项:
- 从源字符串的第一个字符开始往后数num个字符追加到目标空间的后面,外加一个终止字符。
- 如果源字符串的长度小于 num,则仅复制终止字符之前的内容。
模拟实现:
char* my_strncat(char* dest, const char* src, int sz) { assert(dest && src); char* ret = dest; //找目标空间的\0 while (*dest != '\0') { dest++; } //追加 while (sz) { *dest++ = *src++; sz--; } *dest = '\0'; return ret; } int main() { char arr1[20] = "abc\0xxxxxxxxxxx"; my_strncat(arr1, "defjhigk", 3); printf("%s\n", arr1); return 0; }
七:strncmp
strncmp:长的受限的字符串比较函数
int strncmp ( const char * str1, const char * str2, size_t num );
注意事项:
比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。
模拟实现:
int my_strncmp(const char* str1, const char* str2, int sz) { assert(str1 && str2); while (sz) { if (*str1 < *str2) { return -1; } else if (*str1 > *str2) { return 1; } else if(*str1 == '\0'||*str2 =='\0')//当有一个为'\0',说明比较就可以结束了 { if (*str1 == '\0' && *str2 == '\0')//如果二者都是'\0',说明两个字符串相等 { return 0; } else if(*str1 =='\0')//如果str1为'\0',说明str1小,str2大 { return -1; } else//如果src为'\0',说明str1大,str2小 { return 1; } } sz--; str1++; str2++; } } int main() { int ret = my_strncmp("abcdef", "abcd", 5); printf("%d\n", ret); return 0; }
八:strstr
strstr:字符串查找函数
const char * strstr ( const char * str1, const char * str2 );
注意事项:
- 在str1指向的字符串中查找str2指向的字符串
- 返回一个指向str1中第一次出现的str2的指针
- 如果 str2 不是 str1 的一部分,则返回一个空指针
- 匹配过程不包括终止空字符,但它到此为止
模拟实现:
char* my_strstr(char* str1, char* str2) { assert(str1 && str2); if (*str2 == '\0') { return str1; } char* s1 = str1; char* s2 = str2; char* cp = str1; while (*cp) { s1 = cp; s2 = str2; while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2) { s1++; s2++; } if (*s2 == '\0') { return cp; } cp++; } return NULL; } int main() { char arr1[] = "abbvcbcbbdbbvbnui"; char arr2[] = "bbvb"; char* ret = my_strstr(arr1, arr2); if (ret == NULL) { printf("找不到\n"); } else { printf("%s\n", ret); } return 0; }
九:strtok
strtok:字符串拆分函数
char * strtok ( char * str, const char * sep );
注意事项:
sep参数是个字符串,定义了用作分隔符的字符集合
第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记
strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记
如果字符串中不存在更多的标记,则返回 NULL 指针
代码实现:
int main() { char arr[] = "konglong@qq.com"; char* p = "@."; char buf[20] = { 0 }; strcpy(buf, arr); char* ret=NULL; for (ret = strtok(buf, p); ret != NULL; ret = strtok(NULL, p)) { printf("%s\n", ret); } return 0; }