我试图逐字逐句地阅读文本文档的内容,然后将其复制到字符串数组中。首先我打开文件,然后使用fscanf,而我读到的文字是' x'。然后将该x分配给数组,假设最大字长为50.内部i打印x和数组值。两者都打印正确的值。但是后来如果我打印出数组的内容,那么每件事都会出错。所有数组字都具有相同的值。这是文件中的最后一个读取值。 首先我用链表尝试了它,但结果相同。但这也给出了相同的结果。在逻辑块之外,所有数组值或节点值都具有最后读取的字。 请帮帮我...
int i=0,wCnt=0,j;
int N=600;
char **word_array = (char **) calloc(N,sizeof(char*));
if(f = fopen("input.txt","r"))
{
/* assumes no word exceeds length of 150 */
while (fscanf(f, " %149s", x) == 1)
{
if(wCnt==N){
N = N+400;
realloc(word_array,N);
}
//printf("x=%s\t",x);
word_array[i] = (char *) calloc(50,sizeof(char));
word_array[i] = x;
printf("x=%s arr=%s\t",x,word_array[i]); // Gives correct output
wCnt++;
i++;
}
// Here the code goes goes wrong. The last word gets print 137 times(wCnt)
for(j=0;j<wCnt;j++)
{
printf("%d->%s\n",j,word_array[j]);
}
}
我得到的输出是:
0->growing
1->growing
2->growing
3->growing
..
当&#39;成长&#39;是文件中的最后一个词。但是,当我打印出&#39; X&#39;在while循环中,我得到了正确的输出,看起来像:
x =在x =最近x =年x =有x =有x =已x = a x =正在增长
答案 0 :(得分:2)
我没有看到'x'的声明,但是假设它是char *。在线
word_array[i] = x;
您没有将字符串复制到表中,只是将第一个char *设置为指向x。解决方案是使用strcpy或类似的,可能是这样的:
strcpy(word_array[i], x);
答案 1 :(得分:2)
此代码有多个问题,包括:
realloc()
x
的地址保存为当前单词的指针。其中的第三个会通过以下方式表现出来:(a)泄漏内存;(b)单词表中的所有条目都具有相同的地址(本地x缓冲区)
我很确定你正在寻找这样的东西,它解决了上面的每一项。
FILE *f = NULL;
int i=0,j;
int N=600, M=400;
char x[150];
// allocate initial table of pointers, all set to null.
char **word_array = calloc(N,sizeof(*word_array));
if (word_array == NULL)
{
perror("Failed to allocate pointer array");
exit(EXIT_FAILURE);
}
if((f = fopen("input.txt","r")))
{
/* assumes no word exceeds length of 150 */
while (fscanf(f, " %149s", x) == 1)
{
if(i == N)
{
// attempt resize of table, result stored in a temporary
// a NULL return means resizing couldn't happen and we're
// not left with much we can do about it.
void *tmp = realloc(word_array, (N+M) * sizeof(*word_array));
if (tmp == NULL)
{
perror("Failed to expand pointer array");
exit(EXIT_FAILURE);
}
// resize worked. make sure the expansion area contains
// NULL pointers, as we haven't set them yet. then update
// the new size limit.
word_array = tmp;
memset(word_array+N, 0, M*sizeof(*word_array));
N += M;
}
// compute length *once*
size_t wlen = strlen(x);
// use computed length to allocate a dynamic buffer large
// enough to hold the incoming data. again, check for
// failure before proceeding.
word_array[i] = malloc((wlen+1) * sizeof(char));
if (word_array[i] == NULL)
{
perror("Failed to duplicate string");
exit(EXIT_FAILURE);
}
// allocation succeeded. We don't need strcpy
// since we already know how much data to copy
// over (wlen+1, the +1 for the terminating null char)
memcpy(word_array[i], x, wlen+1);
// output string from pointer array to prove that worked
printf("%d ==> %s\n", i, word_array[i]);
// adjust to next slot to populate in the pointer array
++i;
}
// finished with file.
fclose(f);
}