C语言字符串处理函数库
2015-08-30 06:56
721 查看
C语言的字符串处理函数库包括复制函数、拼接函数、比较函数、搜索函数等,这些函数的声明都位于头文件
上述函数的第一个参数都为复制的目的,而第二个参数都为复制的源。
<string.h>。使用这些函数时,需要使用
#include<string.h>指令将头文件包含到文件中。
复制函数
复制函数的功能是将字符(节)从内存的一处(源)移动到另一处(目的),包括以下几个函数:void *memcpy(void *s1, const void *s2, size_t n); void *memmove(void *s1, const void *s2, size_t n); char *strcpy(char *s1, const char *s2); char *strncpy(char *s1, const char *s2, size_t n);
上述函数的第一个参数都为复制的目的,而第二个参数都为复制的源。
memcpy函数从字节数组
s2向
s1复制
n个字节。如果源和目的有重叠,那么使用
memcpy会有问题。
memmove函数可以在源和目的重合时正常处理,在其他方面与
memcpy相同。
strcpy将一个以空字符结尾的字符串
s2复制给
s1。
strncpy跟
strcpy一样,只不过它限制了复制的字符的个数,最多复制
n个字符。如果
n过小,那么
strncpy就不能复制末尾的空字符,如果
n比源字符串长度大,
strncpy在遇到空字符后会不断向目的字符串追加空字符,直到达到
n个。同时
strcpy和
strncpy在源和目的重叠时也会有问题的。
memcpy、
memmove和
strncpy函数可用于包括字符在内的任何内存块,而
strcpy函数只适合字符串,它会持续复制字符,直到遇到源字符中的空字符为止。
/************************************** * string_copy_function.c * * * * C语言字符串处理函数库中的复制函数 * **************************************/ #include <stdio.h> #include <string.h> #define PRINT(dest, i, n) for(i = 0; i < n; i++) printf("%c, ", dest[i]); int main() { char source[] = {'h', 'o', 't', '\0', 't', 'e', 'a'}; char dest[7]; memcpy(dest, source, 3); int i = 0; PRINT(dest,i,7); printf("\n"); memcpy(dest, source, 4); PRINT(dest,i,7); printf("\n"); memcpy(dest, source, 7); PRINT(dest,i,7); printf("\n"); memset(dest, '\0', sizeof(dest)); memmove(dest, source, 3); PRINT(dest,i,7); printf("\n"); memmove(dest, source, 4); PRINT(dest,i,7); printf("\n"); memmove(dest, source, 7); PRINT(dest,i,7); printf("\n"); memset(dest, '\0', sizeof(dest)); strcpy(dest, source); PRINT(dest,i,7); printf("\n"); memset(dest, '\0', sizeof(dest)); strncpy(dest, source, 3); PRINT(dest,i,7); printf("\n"); strncpy(dest, source, 4); PRINT(dest,i,7); printf("\n"); strncpy(dest, source, 7); PRINT(dest,i,7); printf("\n"); return 0; }
拼接函数
拼接函数包括以下两个函数:char *strcat(char *s1, const char *s2); char *strncat(char *s1, const char *s2, size_t n);
strcat函数将它的第二个参数
s2追加到第一个参数
s1的末尾。
s1和
s2必须都是以空字符结尾的字符串。
strcat会用s2的第一个字符覆盖
s1的空字符,并在拼接字符串的后边添加空字符。
strncat与
strcat功能相同,只是限制了从
s2中取出拼接到
s1的字符个数。
/************************************** * string_cat_function.c * * * * C语言字符串处理函数库的拼接函数 * **************************************/ #include <stdio.h> #include <string.h> int main() { char str[7] = "tea"; puts(str); strcat(str, "bag"); puts(str); char str1[7]= "tea"; strncat(str1, "bag", 2); puts(str1); char str2[7] = "tea"; strncat(str2, "bag", 3); puts(str2); char str3[7] = "tea"; strncat(str3, "bag", 4); puts(str3); return 0; }
比较函数
比较函数包括以下几种:int memcmp(const void *s1, const void *s2, size_t n); int strcmp(const char *s1, const char *s2); int strncmp(const char *s1, const char *s2, size_t n); int strcoll(const char *s1, const char *s2); size_t strxfrm(char *s1, const char *s2, size_t n);
memcmp、
strcmp和
strncmp函数以指向字符(字节)数组的指针为参数,逐个比较两个字符(字节)数组的每个字符。根据比较结束时第一个字符(字节)数组中的字符(字节)是小于、等于或大于第二个字符(字节)数组中的字符(字节)而返回-1,0或1。三个函数的主要区别是在于何时结束比较,如果第一个不同的字符在
memcmp和
strncmp的范围
n之内,则三者相同。否则,
strcmp在遇到空字符停止比较,
memcmp不关心空字符,在比较的字节数达到
n个时停止比较,
strncmp结合了上述两个函数的特点,在达到
n个字符或遇到空字符时停止比较。
strcroll和
strcmp功能相似,只不过比较结果依赖于本地化设置(根据不同的地点比较结果不同)。然而
strcoll函数的速度不是很快,当这是个问题或者希望在改变本地设置而不影响比较结果的话,可以使用
strxfrm函数,
strxfrm将第二个参数进行本地化转换,并将转换结果放在第一个参数,参数
n限制了转换的字符个数。
/*************************************** * string_cmp_function.c * * * * C语言字符串处理函数库的比较函数 * ***************************************/ #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char s1[] = {'b', 'i', 'g', '\0', 'c', 'a', 'r'}; char s2[] = {'b', 'i', 'g', '\0', 'c', 'a', 't'}; if (memcmp(s1, s2, 3) == 0) printf("memcmp(3): s1和s2的前%d个字符相同\n", 3); else printf("memcmp(3): s1和s2的前%d个字符不完全相同\n", 3); if (memcmp(s1, s2, 4) == 0) printf("memcmp(4): s1和s2的前%d个字符相同\n", 4); else printf("memcmp(4): s1和s2的前%d个字符不完全相同\n", 4); if (memcmp(s1, s2, 7) == 0) printf("memcmp(7): s1和s2的前%d个字符相同\n", 7); else printf("memcmp(7): s1和s2的前%d个字符不完全相同\n", 7); if (strcmp(s1, s2) == 0) printf("strcmp: s1和s2字符串相同\n"); else printf("strcmp: s1和s2字符串不同\n"); if (strncmp(s1, s2, 3) == 0) printf("strncmp(%d): s1和s2字符串相同\n", 3); else printf("strncmp(%d): s1和s2字符串不相同\n", 3); if (strncmp(s1, s2, 4) == 0) printf("strncmp(%d): s1和s2字符串相同\n", 4); else printf("strncmp(%d): s1和s2字符串不同\n", 4); if (strncmp(s1, s2, 7) == 0) printf("strncmp(%d): s1和s2字符串相同\n", 7); else printf("strncmp(%d): s1和s2字符串不同\n", 7); if (strcoll(s1, s2) == 0) printf("strcoll: s1和s2字符串相同\n"); else printf("strcoll: s1和s2字符串不同\n"); char original[] = "HelloWorld"; printf("original: %s\n", original); size_t len = strxfrm(NULL, original, 0); char *transformed = malloc(len + 1); strxfrm(transformed, original, len); printf("transformed: %s\n", transformed); return 0; }
搜索函数
搜索函数包括以下几个:void *memchr(const void *s, int c, size_t n); char *strchr(const char *s, int c); char *strrchr(const char *s, int c); char *strpbrk(const char *s1, const char *s2); size_t strcspn(const char *s1, const char *s2); size_t strspn(const char *s1, const char *s2); char *strstr(const char *s1, const char *s2); char *strtok(char *s1, const char *s2);
strchr函数在字符串
s中搜索字符
c,它会返回一个指向
s中第一个字符
c的指针,如果没找到,则返回空指针。当遇到空字符时停止搜索。
memchr函数在搜索了
n个字符后停止搜索,返回第一个字符
c的指针,若未找到,则返回空指针。
strrchr与
strchr类似,只是从字符串
s的空字符开始,反向搜索字符
c。如果找到,则返回反向第一个字符
c的地址,若未找到返回空指针。
strpbrk函数从
s1中寻找与
s2中任意一个字符匹配的第一个字符,并返回指向它的指针。若找不到,则返回空。
strspn函数从字符串
s1中搜索字符集
s2,并返回字符组中第一个不属于给定字符集中的字符的下标,而
strcspn函数返回第一个属于给定字符集中的字符的下标。
strstr函数在字符串
s1中搜索字符串
s2,返回找到的第一处匹配子串的指针,如果找不到,则返回空。
strtok函数在
s1中搜索,查找一个非空字符序列(称作记号),这个序列不包括
s2中指定的字符。将找到的记号后面的那个字符替换为一个空字符标记该记号的末尾,然后返回一个指向该记号的首字符的指针。使用
strtok(NULL,s2)就可以继续上一次的
strtok函数调用,直到其返回一个空指针为止。
/************************************** * string_search_function.c * * * * C语言字符串函数库的搜索函数 * **************************************/ #include <stdio.h> #include <string.h> #include <stddef.h> int main() { char *p = NULL; char str[] = "Form follows functions"; p = strchr(str, 'f'); int index = -1; if (p != NULL) { index = p - str; printf("f字符第一次出现在第%u个字符\n", (unsigned int)(index)); } p = strchr(p + 1, 'f'); if (p != NULL) { index = p - str; printf("f字符第二次出现在第%u个字符\n", (unsigned int)(index)); } p = memchr(str,'f', 5); if (p == NULL) printf("字符串的前5个字符没有字符'f'\n"); p = strrchr(str, 'f'); if (p != NULL) { index = p - str; printf("f字符反向第一次出现在第%u个字符\n", (unsigned int)(index)); } p = strpbrk(str, "mn"); if (p != NULL) { index = p - str; printf("m或n第一次出现的位置为%u,字符为%c\n", (unsigned int)index, *p); } int index2 = strspn(str, "mn"); if (index >= 0) printf("第一个既不是m也不是n的字符位置为%d\n", index2); index2 = strcspn(str, "mn"); if (index2 >= 0) printf("第一个m或n出现的字符位置为%d,为字符%c\n", index2, str[index2]); char day[] = "April 28, 1998"; p = strtok(day, " "); printf("month: %s,", p); p = strtok(NULL,", "); printf("day: %s,", p); p = strtok(NULL, " "); printf("year: %s\n", p); return 0; }
其他函数
memset函数将一个字符的多个副本存储到指定的内存区域,其原型为:
void *memset(void *s, int c, size_t n);
strlen返回字符串的长度,不包括字符串末尾的空字符,其原型为
size_t strlen(const char *s);
strerror当输入存储在
errno的错误码时,会返回一个指向描述这种错误的字符串的指针。其原型为
char *strerror(int errnum);
/************************************** * string_other_function.c * * * * C语言字符串处理函数中的其他函数 * *************************************/ #include <stdio.h> #include <string.h> #include <math.h> #include <errno.h> int main() { int a[10] = {1,2,3,4,5,6,7,8,9,10}; int i = 0; for (; i < 10; i++) printf("%d ", a[i]); printf("\n"); memset(a, 0, sizeof(a)); for (i = 0; i < 10; i++) printf("%d ", a[i]); printf("\n"); char temp[] = "hello world"; printf("temp字符数: %u\n",(unsigned)strlen(temp)); printf("temp: %s\n", temp); memset(temp, '\0', sizeof(temp)); printf("temp: %s\n", temp); sqrt(-1); puts(strerror(errno)); return 0; }
参考文献
K.N. King 著,吕秀峰 译. C语言程序设计-现代方法. 人民邮电出版社相关文章推荐
- Vc++ 控件用法总结之List Control
- C++ Primer : 第十二章 : 文本查询程序
- malloc、calloc、realloc的区别
- C++11 并发
- C语言中sizeof与strlen区别
- C++ string类
- 通过实例浅析Python对比C语言的编程思想差异
- LeetCode-Binary Tree Paths -解题报告
- C++写dll文件用C#调用
- C语言中运算符及其优先级
- c++多态原理
- 设计模式在游戏中的应用--观察者模式(十)
- Effective C++——条款10条,条款11和条款12(第2章)
- Fedora下Eclipse建立c++工程的"Unresolved inclusion: <iostream>"问题
- 关于c++字符串的while(*temp++)
- c++字符串学习
- Apriori算法及C++实现
- ptmalloc,tcmalloc和jemalloc内存分配策略研究
- 编程经验C++
- C++拷贝构造函数