转载请注明出处!
在C语言中没有专门的字符串数据类型,字符串都是以字符串常量和字符数组的形式出现。其实字符串就是一串零个或多个字符,并且以一个位模式为全0的NUL字节结束。因此,字符串所包含的字符内部不能出现NUL字节。头文件string.h包含了使用字符串函数所需的原形和声明,尽管并非必须,但在程序里包含这个头文件确实是个好主意,因为有了它所包含的原型,编译器可以更好地为你的程序执行错误检查。
下面列举了在使用C库中字符串函数时的注意事项,此内容会持续的更新!
size_t strlen(cha const *string);注意函数的返回值为无符号整数,size_t在stddef.h中定义,如果在表达式中使用无符号整数可能导致不可预料的结果。例如下面的两个表达式看上是相等的:
if (strlen(x) >= strlen(y))... if(strlen(x) - strlen(y) >= 0)...
我们经常使用的字符串函数都是"不受限制的",即它们都是通过寻找字符串参数结尾的NUL字符来判断它的长度的。这些函数一般都会指定一块内存用于存放结果字符串,程序员需要自己保证结果结果字符串不能超过该块内存区域。
用于复制字符串的函数strcpy的函数原型如下:
char * strcpy(char *dst, const char*src);
该函数会将src中的字符串复制到dst中,如果两个字符串中存在重叠的部分,其结果是未定义的。目标参数以前的内容会被覆盖并丢失,即使src比dst的长度更短。例如:
<pre name="code" class="cpp">char str[] = "Hello, China!" strcpy(str, "NiHao"); printf("str = %s\n", str); Output: NiHao程序员必须保证目标字符数组的空间足以容纳被复制的字符串,如果字符串比字符数组长,多余的字符同样地被复制,它们会覆盖原先存储于数组之后的内存空间的数据,strcpy无法解决这个问题,他不能判断目标字符数组的长度!
strcat讲一个字符串拼接到另一个字符串的后面,其原型如下:
char *strcat(char *dst, char const *src);strcat要求dst中包含一个字符串(可以为空字符串),其搜索到该字符串的末尾,并将src中的字符串拷贝到该位置。如果src和dst存在重叠,其结果是未定义的。同样,程序员必须保证dst字符数组的空间能容纳dst和src总的字符长度!
字符串的比较原理为对两给字符串逐个比较,直到发现不匹配为止。strcmp的函数原型为:
int strcmp(char const *s1, char cosnt *s2);
对于字符串是否相等的判断有的人写法如下:
if(!strcmp(s1,s2)) 把这个返回值当做布尔值进行测试一种坏风格,因为它有三个不同的返回值:小于,等于,大于。更好地方法为 if(strcmp(s1, s2) == 0)
strcmp的参数必须以NUL字节结尾,否则其会对参数后面的字节进行比较,这样做是没有意义的!
C库中包含其他一些字符串处理函数,它们提供一个显式的长度用于限制进行复制和比较的字符串的长度,该机制可以有效的防止难以预料的长字符串从他们的目标中溢出。同样,这些函数不能结果源参数和目标参数存在重叠的问题。
这些函数的原型如下:
char *strncap(char *dst, const char *src, size_t len); char *stncat(char *dst, cosnt char *src, size_t len); int strncmp(char cosnt *s1 , char const*s2, size_t len);
char buffer[BSIZE]; strncpy(buffer, name, BSIZE); buffer[BSIZE - 1] = 0;
如果name长度小于BSIZE,那么最后的赋值语句没有任何效果,但是如果name太长以至于超过了BSIZE,那么最后的赋值语句可以控制buffer以NUL字节结束,以后涉及该字符串的操作都可以正确执行。
strncat总是在目标字符串的末尾添加一个NUL字节,len没有讲原先的字符长度包含在内,其只管将src中len字符拷贝到src中,并在src的末尾添加一个NUL字节,其不管src出去原先存在的字符串剩下的空间够不够。
strncmp最多比较len个字节,如果两个字符串在len个字符之前存在不等的字符,该函数返回,如果两个字符串的前len个字符相等,函数就返回零。