0

我编写了代码来将一个字符串复制到另一个字符串中,但每个字符之间有一个空格。当我运行代码时,字符串后面有“垃圾”。但是,如果最后的for循环没有注释,后面就没有垃圾了。有谁知道为什么会这样?

#include<stdio.h>
#include<string.h>

#define MAX_SIZE 20
main ()
{
    char name[MAX_SIZE+ 1]; 
    char cpy[(MAX_SIZE * 2) + 1];

    gets(name);

    int i = 0;

    while (name[i] != '\0' && i < MAX_SIZE)
    {
        cpy[(i * 2)] = name[i];
        cpy[(i * 2) + 1] = ' ';
        i++;
    }

    cpy[strlen(cpy)] = '\0';    

    printf("%s\n", cpy);

    //for (i = 0; i < strlen(cpy); ++i) {
    //    printf("%c", cpy[i]);
    //}

}
4

4 回答 4

5

线

cpy[strlen(cpy)] = '\0';

将不起作用,因为cpy它不是 null 终止的,因此strlen将在结束后读取,name直到它崩溃或找到零字节的内存。您可以通过将该行更改为

cpy[i*2] = '\0';

如果在函数末尾取消注释 for 循环似乎可以解决问题,我只能猜测在调用i之前会重置为 0 printf,这意味着printfcpy. 如果这是正在发生的事情,那么它的行为非常未定义,因此不能依赖。

于 2013-03-05T13:25:20.790 回答
2
 while (name[i] != '\0' && i < MAX_SIZE)
    {
        cpy[(i * 2)] = name[i];
        cpy[(i * 2) + 1] = ' ';
        i++;
    }
 cpy[(i * 2)] = 0x0;

您必须空终止字符串。

于 2013-03-05T13:26:09.987 回答
1

因为你知道你正在使用一个字符串,所以如果你用空字符初始化你的“cpy”数组是一件好事:

 char cpy[(MAX_SIZE * 2) + 1]  = "\0";

否则,我同意 simonc 的回答。

于 2013-03-05T13:35:32.803 回答
1

为了完整起见:

char* pcpy = cpy;
for (char const* p = fgets(name,sizeof(name)/sizeof(*name),stdin); p && *p; ++p) {
  *pcpy++ = *p;
  *pcpy++ = ' ';
}
*pcpy = 0;

您应该使用fgets, 而不是gets为了防止您的堆栈因数据溢出而损坏。其次,您必须手动终止存储在cpy数组中的字符串,因为strlen只需计算字符数,直到第一个零。因此,如果您尚未终止cpy,则结果strlen(cpy)将是未定义的,并且很可能会使您的程序崩溃。

于 2013-03-05T13:37:08.973 回答