当前位置:嗨网首页>书籍在线阅读

18-strncat()函数

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

11.5.3 strncat()函数

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

程序清单11.19  join_chk.c 程序

/* join_chk.c -- 拼接两个字符串,检查第1个数组的大小 */
#include <stdio.h>
#include <string.h>
#define SIZE 30
#define BUGSIZE 13
char * s_gets(char * st, int n);
int main(void)
{
     char flower[SIZE];
     char addon [] = "s smell like old shoes.";
     char bug[BUGSIZE];
     int available;
     puts("What is your favorite flower?");
     s_gets(flower, SIZE);
     if ((strlen(addon) + strlen(flower) + 1) <= SIZE)
          strcat(flower, addon);
     puts(flower);
     puts("What is your favorite bug?");
     s_gets(bug, BUGSIZE);
     available = BUGSIZE - strlen(bug) - 1;
     strncat(bug, addon, available);
     puts(bug);
     return 0;
}
char * s_gets(char * st, int n)
{
     char * ret_val;
     int i = 0;
     ret_val = fgets(st, n, stdin);
     if (ret_val)
     {
          while (st[i] != '\n' && st[i] != '\0')
               i++;
          if (st[i] == '\n')
               st[i] = '\0';
          else 
               while (getchar() != '\n')
                    continue;
     }
     return ret_val;
}

下面是该程序的运行示例:

What is your favorite flower?
Rose
Roses smell like old shoes.
What is your favorite bug?
Aphid
Aphids smell

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