C字符串:使用strcpy和strcat后出现在内存中的随机字符

时间:2014-05-01 10:18:49

标签: c string strcpy strcat

我试图从文件中删除文件扩展名,以便我可以使用子字符串" opt.s"重命名该文件。我通过以下简单的示例程序执行此操作:

 char in[5] = "hel.s";
 char test[40];
 strncpy(test,in,strlen(in)-2);
 char result[50];
 strcpy(result,strcat(test,"opt.s"));
 printf(" %s ",result);

我得到的输出有所不同,但通常看起来如下:

 helþ(opt.s 

所以基本上随机数字出现在" hel"和" opt.s"。这是什么原因?我是否使用了strcpy错误或是strcat导致问题?

2 个答案:

答案 0 :(得分:2)

char in[5] = "hel.s";

in NOT 是一个字符串:它没有终止'\0'个字符。你不能在字符串函数中使用。

strncpy(test, in, strlen(in) - 2); // invalid use of strlen

但是,strncpy()不是字符串函数(它在src数组中不需要终止NUL;它不必在dst数组中写入终止NUL)。
如果它按照我的预期工作,那么生成的test数组也是 NOT 一个字符串......并且您不能将它与字符串函数一起使用。

strcpy(result, strcat(test, "opt.s")); // invalid use of strcat

答案 1 :(得分:2)

这是不正确的:

char in[5] = "hel.s";

字符串需要六个而不是五个字符(第六个字符用于空终止符)。如果没有它,则字符串无法终止,导致strlenstrcat和其他对终止字符串起作用的函数失败并出现未定义的行为。

要修复,请从声明中删除5,让编译器为您决定长度:

char in[] = "hel.s";

此外,您对strncpy的使用无效:它隐式附加空终结符

  

如果source长于num,则不会在目标末尾隐式附加空字符。因此,在这种情况下,destination不应被视为空终止的C字符串(读取它会溢出)。

这一行

strncpy(test,in,strlen(in)-2);

始终生成未终止的字符串,导致后续调用strcat失败。要解决此问题,您需要自己添加终止符:

size_t len = strlen(in)-2;
memcpy(test, in, len); // Do not use strncpy
test[len] = '\0';