C语言字符函数和字符串函数
字符分类函数
C语言中有一系列的函数是做字符分类的,包含在头文件 ctype.h中

字符转换函数
C语言提功了2个字符转换函数
1 | int tolower(int c) // 将参数传进去的大写字母转小写 |
1 | int i = 0; |

strlen
用于求一个字符串的长度,包含在头文件<string.h>中
语法格式如下:
1 | size_t strlen(const char* str) |
字符串以 \0 结尾,strlen 是统计 \0 之前的字符个数
参数指向的字符串必须以 \0 结尾
返回值类型是 size_t ,是无符号型
1
2
3
4
5
6
7
8
9
10char arr1[] = "abc";
char arr2[] = "abcdef";
if (strlen(arr1) - strlen(arr2) > 0)
{
printf("arr1 > arr2\n");
}
else
{
printf("arr1 <= arr2\n");
}
在这里强转成 int 在符合逻辑
1 | // strlen 返回值类型是 size_t, 是无符号的 |

strlen 的模拟
简单模拟一下 strlen 的基本功能
1 | int my_strlen_1(const char* arr) |
1 | char arr1[] = "abcdefghjk"; |

strcpy

strcpy 用于拷贝字符串,包含在头文件<string.h>中
语法格式
1 | char* strcpy(char * destination, const char * source ); |
将 source 拷贝到 destination 中
- 源字符串必须以 ‘\0’结尾
1
2
3
4char arr1[] = { 'a','b','c' };
char arr2[] = { "" };
strcpy(arr2, arr1);
printf("%s\n", arr2);
- 会将源字符串的 ‘\0’也拷贝过来
1
2
3
4
5
6
7
8int main()
{
char arr1[] = "hello world!";
char arr2[20] = "";
strcpy(arr2, arr1);
printf("%s\n", arr2);
return 0;
}
- 目标空间必须够大
1
2
3
4char arr1[] = "hello world!";
char arr2[5] = "";
strcpy(arr2, arr1);
printf("%s\n", arr2);
- 目标空间必须允许修改
1
2
3
4
5
6// 目标空间必须允许修改
char arr1[] = "hello world!";
char *p = "";
strcpy(p, arr1);
printf("%s\n", p);
return 0;
strcpy 的模拟实现
简单模拟一下 strcpy 的基本功能
1 | char* my_strcpy(char* dest,const char* sour) |

strcat
语法格式
1 | char * strcat ( char * destination, const char * source ); |
用于将 source 字符串追加在 destination 后,包含在头文件<string.h>中
1 | char arr1[20] = "I LOVE"; |

源字符串必须以 ‘\0’结尾
1
2
3
4char arr1[20] = "hello "; // 目标字符串有 \0
char arr2[] = { 'w','o','r','l','d','!' }; // 源字符串无 \0
strcat(arr1, arr2);
printf("%s\n", arr1);目标字符串必须要有 ‘\0’
1
2
3
4char arr1[20] = {'h','e','l','l','o'}; // 目标字符串无 \0
char arr2[] = " world!"; // 源字符串有 \0
strcat(arr1, arr2);
printf("%s\n", arr1);

这里虽然进行了正确的追加,但通过调试看到 arr1 在没有完全初始化的时候是
自动分配了 ‘\0’ 的。但是没办法保证什么时候没有初始化的内存空间都是自动分
配 ‘\0’。C 标准明确:缺少\0使用strcat属于非法写法。
目标空间必须足够大
1
2
3
4char arr1[6] = "abcde";
char arr2[] = "fghj";
strcat(arr1, arr2);
printf("%s\n", arr1);
目标必须是可修改的
1
2
3
4char* str = "I LOVE "; // 常量字符串
char arr[] = "C!";
strcat(str, arr);
printf("%s\n", str);
strcat的模拟实现
来简单实现以下 strcat 的基本功能
1 | char* my_strcat(char* dest, const char* sour) |

strcmp
语法格式
1 | int strcmp ( const char * str1, const char * str2 ); |
用于比较两个字符串
str1 > str2 ,返回大于 0 的数字
str1 和 str2 相等,则返回0
str1 < str2 ,返回小于 0 的数字
比较的依据是比较两个字符串上对应字符的 ASCII 值,如果相等就继续比
较,如果存在大小关系就返回对应的值
1 | char arr1[] = "abcd"; |

strcmp 的模拟实现
1 | 来简单实现以下 strcmp 的基本功能 |
1 | int main() |

strncpy
语法格式
1 | char * strncpy ( char * destination, const char * source, size_t num ); |
- 和 strcpy 类似,但是是从 source 中拷贝 num 个元素到 destination 中
1 | char arr1[20] = "abcde"; |

- 如果 source 的长度小于 num ,则在完成拷贝后,在 destination 后追加 0 ,直到满足 num 个
1
2
3
4char arr1[20] = "xxxxxxxxxxxxxxx";
char arr2[] = "world!";
strncpy(arr1, arr2, 10);
printf("%s\n", arr1);
strncat
语法格式
1 | char * strncat ( char * destination, const char * source, size_t num ); |
与 strcat 类似,但是是从 source 中追加 num 个元素到 destination 的末尾处
1
2
3
4char arr1[20] = "hello ";
char arr2[] = "world!";
strncat(arr1, arr2, 3);
printf("%s\n", arr1);
如果 source 的长度小于 num ,则只追加 source 中 \0 前的字符在 destination 的末尾处
1 | char arr1[20] = "hello "; |

strncmp
语法格式
1 | int strncmp ( const char * str1, const char * str2, size_t num ); |
- 与 strcmp 类似,但是是比较 str1 和 str2 的前 num 个字符
1 | char arr1[] = "abcd"; |

strstr
语法格式
1 | const char * strstr ( const char * str1, const char * str2 ); |
返回 str2 在 str1 中第一次出现的位置
找不到的话返回空
1 | char arr1[] = "hello1 hello2 hello3 hello4"; |

strstr的模拟
1 | char* my_strstr(const char* str1, const char* str2) |

strtok
语法格式
1 | char * strtok ( char * str, const char * delimiters ); |
delimiters 指向的字符串定义了用作分隔符的字符合集
str 指向的字符串包含0个或多个由 delimiters 字符串中一个或者多个分隔
符分割的标记
strtok 函数找到 str 中的下一个标记,并用 \0 结尾,返回一个指向这个标
记的指针1
2
3
4
5
6
7// strtok 的使用
// strtok 函数找到 str 中的下一个标记,并用 \0 结尾,返回一个指向这个标记的指针,这说明使用 strtok 这个函数后
// str 指向的字符串可能会被修改
char arr1[] = "xxxxx@qq.com";
const char* str = "@.";
strtok(arr1, str);
printf("%s\n", arr1);

strtok 函数的第一个函数不为 NULL, 函数将 str 中第一个标记,strtok 函数
将保存它在字符串中的位置
strtok 函数的第一个函数为 NULL, 函数将在同一个字符串中被保存的位置
开始,查找下一个标记保存它在字符串中的位置
1 | // strtok 的使用 |

- 如果字符串中不存在更多的标记,则返回 NULL
1
2
3
4
5
6
7
8
9
10char arr1[] = "xxxxx@qq.com";
const char* str = "@.";
char* p1 = strtok(arr1, str);
printf("%s\n", p1);
char* p2 = strtok(NULL, str);
printf("%s\n", p2);
char* p3 = strtok(NULL, str);
printf("%s\n", p3);
char* p4 = strtok(NULL, str);
printf("%s\n", p4);
strerror
语法格式
1 | char * strerror ( int errnum ); |
返回参数部分的错误码对应的错误信息的字符串地址
在不同的系统和C语言标准库中规定了一些错误码,一般放在 errno.h 中。
C语言程序启动时,会自动使用一个全局变量 errno 来记录当前程序的错误码,
默认为 0 表示没有错误,当使用标准库函数出现某种错误时,就会将对应的错误
码放到 errno 中
strerror 可以将对应的错误信息字符串的地址返回
1 | for (int i = 0;i <= 10;i++) |

perror
语法格式
1 | void perror ( const char * str ); |
该函数先打印传给 perror 的字符串,然后打印冒号,在打印空格,最后打印对应错误
码的错误信息
1 | int main() |




