在C中出现字符串数组重复出现问题

时间:2019-06-03 19:03:30

标签: c arrays pointers fgets

我正在尝试获取未知数量的控制台输入行,使用malloc将每一行转换为String,然后通过每次动态重新分配内存将每个字符串添加到字符串数组中。我的目标是要创建一个数组,其中每个元素都是控制台输入的不同行(while循环应以EOF结尾)。

我的代码在下面。

char * inputString = (char *)malloc(100);
char * aWord = (char *)malloc(1);
char ** listWords = (char **)malloc(1);
int wordCount = 0;

while (fgets(inputString, 100, stdin) != NULL)
{       
    wordCount++;
    *(inputString + (strlen(inputString) - 1)) = '\0';
    aWord = (char *)realloc(aWord, strlen(inputString) + 1);
    aWord = inputString;

    listWords = realloc(listWords, sizeof(char) * wordCount);
    *(listWords + (wordCount - 1)) = aWord;
}

for (int i = 0; i < wordCount; i++)
    printf("%s\n", listWords[i]);

如果要在控制台中输入

abc\n
b\n
cad\n
^Z\n

理论上,我希望我的代码可以打印出来

abc\n
b\n
cad\n

每行控制台输入。而是打印

cad\n
cad\n
cad\n

输入的最后一行。帮助非常感谢

3 个答案:

答案 0 :(得分:1)

您不能使用赋值来复制字符串,而必须使用strcpy()

strcpy(aWord, inputString);

也是

*(listWords + (wordCount - 1)) = aWord;

可以简化为:

listWords[wordCount-1] = aWord;

答案 1 :(得分:1)

首先是这个:

aWord = (char *)realloc(aWord, strlen(inputString) + 1);
aWord = inputString;

在这里您为aWord分配了空间,但是随后用inputString中包含的地址覆盖了返回的地址。因此,您读入的每个字符串最终都会覆盖前一个字符串。您还应该使用malloc而不是realloc,因为您想获得一个新的缓冲区,而不是重用现有的缓冲区。

realloc调用更改为malloc and instead of assigning one pointer to the other, use strcpy`以进行复制。

aWord = malloc(strlen(inputString) + 1);
strcpy(aWord, inputString);

然后在此行:

listWords = realloc(listWords, sizeof(char) * wordCount);

您只能为字符数组分配足够的内存,而不是为字符数组分配 pointers 指针。这样会导致写入超出分配的内存末尾,从而调用undefined beahvior

正确的分配是:

listWords = realloc(listWords, sizeof(char *) * wordCount);

答案 2 :(得分:1)

有三个问题。

首先,realloc不会分配额外的aWord,而是增加/减少了当前aWord的缓冲区,从而可能在释放旧地址的同时还提供了一个新地址。因此aWord = (char *)realloc(aWord, strlen(inputString) + 1)将使内存适应新的大小,但是您将丢失先前写入aWord的内容。请注意,*(listWords + (wordCount - 1)) = aWord将使您的最终列表指向aWord。使用malloc代替realloc

第二,使用aWord = inputString;,让aWord指向inputString,而不是复制其内容。请改用strcpy

char *aWord = malloc(aWord, strlen(inputString) + 1);
strcpy (aWord,inputString);

第三,您需要保留用于字符指针的空间,而不仅仅是字符。

listWords = realloc(listWords, sizeof(char*) * wordCount);