C语言的字符串处理函数库包括复制函数、拼接函数、比较函数、搜索函数等,这些函数的声明都位于头文件
。使用这些函数时,需要使用#include
指令将头文件包含到文件中。
复制函数的功能是将字符(节)从内存的一处(源)移动到另一处(目的),包括以下几个函数:
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
#include
#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
#include
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
#include
#include
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
#include
#include
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
#include
#include
#include
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;
}