2月10日 C Primer Plus学习

11.5.1 strlen()函数

strlen()函数用于统计字符串的长度。下面的函数可以缩短字符串的长度,其中用到了strlen():
void fit(char *string, unsigned int size)
{ if (strlen(string) > size) string[size] = '\0';
}
该函数要改变字符串,所以函数头在声明形式参数string时没有使用 const限定符。
程序清单11.17中的程序测试了fit()函数。注意代码中使用了C字符串常量的串联特性。

程序清单11.17 test_fit.c程序
/* test_fit.c -- 使用缩短字符串长度的函数 */
#include <stdio.h>
#include <string.h>  /* 内含字符串函数原型 */
void fit(char *, unsigned int); 
int main(void)
{ 
    char mesg [] = "Things should be as simple as possible,"
                   " but not simpler.";
    puts(mesg); 
    fit(mesg, 38); 
    puts(mesg); 
    puts("Let's look at some more of the string."); 
    puts(mesg + 39); 
    return 0;
}
void fit(char *string, unsigned int size)
{ 
    if (strlen(string) > size) 
        string[size] = '\0';
}

下面是该程序的输出:
Things should be as simple as possible, but not simpler.
Things should be as simple as possible Let's look at some more of the string.
but not simpler.
fit()函数把第39个元素的逗号替换成'\0'字符。puts()函数在空字符处停止输出,并忽略其余字符。然而,这些字符还在缓冲区中,下面的函数调用把这些字符打印了出来:

puts(mesg + 8);

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


注意
一些ANSI之前的系统使用strings.h头文件,而有些系统可能根本没有字符串头文件。
string.h头文件中包含了C字符串函数系列的原型,因此程序清单11.17要包含该头文件。

11.5.2 strcat()函数

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

11.5.3 strncat()函数

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

strcat()和 gets()类似,也会导致缓冲区溢出。为什么 C11 标准不废弃strcat(),只留下strncat()?为何对gets()那么残忍?这也许是因为gets()造成的安全隐患来自于使用该程序的人,而strcat()暴露的问题是那些粗心的程序员造成的。无法控制用户会进行什么操作,但是,可以控制你的程序做什么。C语言相信程序员,因此程序员有责任确保strcat()的使用安全。

posted @ 2022-02-10 15:14  shucharjer  阅读(33)  评论(0)    收藏  举报