2.10 C Primer Plus 11.5.1~11.5.3 字符串函数(上)

11.5 字符串函数

C库提供了多个处理字符串的函数,ANSI C把这些函数的原型放在 string.h头文件中,包括strlen()、strcat()、strcmp()、 strncmp()、strcpy()和 strncpy()。另外,还有sprintf()函数,其原型在stdio.h头 文件中。

11.5.1 strlen()函数

strlen()函数用于统计字符串的长度。

下面的函数可以缩短字符串的长度,其中用到了strlen():

void fit(char *string, unsigned int size)

{

if (strlen(string) > size)

string[size] = '\0';

}

该函数要改变字符串,所以函数头在声明形式参数string时没有使用 const限定符。

下列示例程序测试了fit()函数:

注意代码中使用了C字符串常量的串联特性。

下面是该程序的输出:

fit()函数把第39个元素的逗号替换成'\0'字符。puts()函数在空字符处停止输出,并忽略其余字符。

然而,这些字符还在缓冲区中,下面的函数调用把 这些字符打印了出来:

puts(mesg + 8);

表达式mesg + 39是mesg[39]的地址,该地址上储存的是空格字符。所以 put()显示该字符并继续输出直至遇到原来字符串中的空字符。

图11.4演示了这一过程:

注意

一些ANSI之前的系统使用strings.h头文件,而有些系统可能根本没有字符串头文件。

string.h头文件中包含了C字符串函数系列的原型,因此上述示例程序中包含了该头文件。

11.5.2 strcat()函数

strcat()(用于拼接字符串)函数接受两个字符串作为参数。该函数把第 2个字符串的备份附加在第1个字符串末尾,并把拼接后形成的新字符串作为 第1个字符串,第2个字符串不变。strcat()函数的类型是char *(即,指向char 的指针)。strcat()函数返回第1个参数,即拼接第2个字符串后的第1个字符 串的地址。

下列示例程序演示了strcat()的用法:

该程序还使用了程序清单11.10的 s_gets()函数。回忆一下,该函数使用fgets()读取一整行,如果有换行符,将 其替换成空字符。

输出结果如下:

从上述输出可以看出,flower改变了,而addon保持不变。

11.5.3 strncat()函数

strcat()函数无法检查第1个数组是否能容纳第2个字符串。如果分配给第一个数组的空间不够大,可以像程序清单11.15那样处理,用strlen()查看第一个数组的长度。注意,要给拼接后的字符串长度加1才够空间存放末尾的空字符。或者,用strncat(),该函数的第三个参数指定了最大添加字符数。例如,strncat(bugs,addon,13)将把addon字符串的内容附加给bugs,在加到第十三个字符或遇到空字符时停止。因此,算上空字符(无论那种情况都要添加空字符),bugs数组应该足够大,以容纳原始字符串(不包含空字符)、添加原始字符串在后面的13个字符串和末尾的空字符。

下列的示例程序使用了这种方法,计算available变量的值,用于表示允许添加的最大字符数:

输出结果如下:

strcat()和gets()类似,都会造成缓冲区溢出。

不废弃strcat()只留下strncat()的原因是:gets()造成的安全隐患来自于使用该程序的人,而strcat()暴露的问题是那些粗心的程序员造成的。无法控制用户会进行什么操作,但是,可以控制你的程序做什么。而C语言相信程序员,因为程序员有责任确保strcat()的使用安全。

posted @ 2022-02-14 22:45  喻雅芬  阅读(53)  评论(0)    收藏  举报