字符串函数
头文件string.h中包含了使用这些字符串函数所需的原型和声明。
1. 字符串长度
size_t strlen(char const *string);
strlen函数返回一个类型为size_t的值。这个类型是在头文件stddef.h中定义的,它是一个无符号整数类型。在表达式中使用无符号数可能导致不可预料的结果。例如,下面两个表达式看上去是相等的:
if (strlen(x) >= strlen(y)) ... if (strlen(x) - strlen(y) >= 0) ...
但事实上它们是不相等的。第1条语句将按照你预想的那样工作,但第2条语句的结果将永远是真。strlen的结果是个无符号数,所以操作符>=左边的表达式也将是无符号数,而无符号数绝不可能是负的。
2. 复制字符串
char *strcpy(char *dst, char const *src);
这个函数把参数src字符串复制到dst参数。如果参数src和dst在内存中出现重叠,其结果是未定义的。函数返回指向目标字符数组的指针。
程序员必须保证目标字符数组的空间足以容纳需要复制的字符串。如果字符串比数组长,多余的字符仍将被复制,它们将覆盖原先存储于数组后面的内存空间的值。
3. 连接字符串
char *strcat(char *dst, char const *src);
strcat函数要求dst参数原先已经包含了一个字符串(可以是空字符串)。它找到这个字符串的末尾,并把src字符串的一份拷贝添加到这个位置。如果src和dst的位置发生重叠,其结果是未定义的。函数返回指向目标字符数组的指针。
和前面一样,程序员必须保证目标字符串数组剩余的空间足以保存整个源字符串。
4. 字符串比较
int strcmp(char const *s1, char const *s2);
如果s1小于s2,strcmp函数返回一个小于零的值。如果s1大于s2,函数返回一个大于零的值。如果两个字符串相等,函数就返回零。
注意“if (strcmp(a, b)) ...”可能并不能像预想的那样工作。当a于b相等时函数返回0,表示的是假。应该将返回值于0相比较。
5. 长度受限的字符串复制函数
char *strncpy(char *dst, char const *src, size_t len);
和strcpy一样,strncpy将源字符串的字符复制到目标数组。然而,它最多向dst写入len个字符。如果src的长度小于len,dst数组就用额外的NULL字节填充到len长度。如果src的长度大于或等于len,那么只有len个字符被复制到dst中。注意!这时它的结果将不会以NULL字节结尾。
strncpy调用的结果可能不是一个字符串。在使用不受限制的函数之前,你首先必须确定字符串实际上是以NULL字节结尾的。例如,考虑下面这个代码段:
char buffer[BSIZE]; ... strncpy(buffer, src, BSIZE); buffer[BSIZE - 1] = '\0';
6. 长度受限的字符串连接函数
char *strncat(char *dst, char const *src, size_t len);
strncat函数对strcat函数的改进是,它从src中最多复制len个字符到目标字符串的后面。而且,strncat函数总是在结果字符串后面添加一个NULL字节。也就是说,strncat最多相目标数组复制len个字符,再加一个结尾的NULL字节,但它不管目标参数的剩余空间够不够。
7. 长度受限的字符串比较函数
int strncmp(char const *s1, char const *s2, size_t len);
与strcmp函数不同的是,strncmp函数最多比较len个字节。
8. 查找一个字符
char *strchr(char const *str, int ch); char *strrchr(char const *str, int ch);
注意它们的第二个参数是一个整数值。但是,它包含了一个字符值。strchr在字符串str中查找字符ch第一次出现的位置,找到后返回一个指向该位置的指针。如果该字符串并不存在于字符串中,函数就返回一个NULL指针。strrchr的功能和strchr基本一致,不过它是从后往前查找的。
9. 查找一组字符中的任意一个
char *srpbrk(char const *str, char const *group);
这个函数返回一个指向str中第1个匹配group中任何一个字符的字符位置。如果未找到匹配,函数返回一个NULL指针。
10. 查找一个子串
char *strstr(char const *s1, char const *s2);
这个函数在s1中查找整个s2第一次出现的起始位置,并返回一个指向该位置的指针。如果s2并没有完整地出现在s1的任何地方,函数将返回一个NULL指针。如果第2个参数是一个空字符串,函数就返回s1。
11. 查找一个字符串的前缀
strspn和strcspn函数用于对字符串起始位置的特定字符计数。
size_t strspn(char const *str, char const *group); size_t strcspn(char const *str, char const *group);
group字符串指定一个或多个字符。strspn返回str起始部分匹配group中任意字符的字符数,strcspn返回str起始部分不与group中任何字符匹配的字符数。
例如:
int len1, len2; char buffer[] = "25,142,330,Smith,J,239-4123"; len1 = strspn(buffer, "0123456789"); len2 = strspn(buffer, ",0123456789";
结果是len1的值为2,len2的值为11。
下面的代码将计算一个指向字符串中第1个非空白字符的指针。
ptr = buffer + strspn(buffer, "\n\r\f\t\v");
12. 查找标记
一个字符串常常包含几个单独的部分,它们彼此被分隔开来。每次为了处理这些部分,你首先必须把它们从字符串中抽取出来。这个任务正是strtok函数所实现的功能。它从字符串中隔离各个单独的称为标记(token)的部分,并丢弃分隔符。它的原型如下:
char *strtok(char *str, char const *sep);
sep参数是个字符串,定义了用作分隔符的字符集合。str参数指定一个字符串,它包含零个或多个由sep字符中一个或多个分隔符分隔的标记。strtok找到str的下一个标记,并将其用NULL结尾,然后返回一个指向这个标记的指针。
strtok函数会修改它所处理的字符串。
如果strtok函数的第1个参数不是NULL,函数将找到字符串的第1个标记.strtok同时将保存它在字符串中的位置。如果strtok函数的第1个参数是NULL,函数将在同一个字符串中从这个被保存的位置开始像前面一样查找下一个标记。如果字符串内部存在更多的标记,strtok函数就返回一个NULL指针。在经典情况下,第1次调用strtok时,向它传递一个指向字符串的指针。然后,这个函数被重复调用,直到它返回NULL为止。
示例:
#include <stdio.h> #include <string.h> void print_token(char *line) { static char whitespace[] = " \t\f\r\v\n"; char *token; for (token = strtok(line, whitespace); token != NULL; token = strtok(NULL, whitespace)) printf("Next token is %s\n", token); }
13. 错误信息
当你调用一些函数,请求操作系统指向一些功能如打开文件时,如果出现错误,操作系统是通过设置一个外部的完整变量errno进行错误代码报告的。strerror函数把其中一个错误代码作为参数并返回一个指向用于描述错误的字符串的指针。函数原型如下:
char *strerror(int error_number);