Word从文档INTO读取C中的字符串数组

时间:2014-09-19 08:41:58

标签: c

我试图逐字逐句地阅读文本文档的内容,然后将其复制到字符串数组中。首先我打开文件,然后使用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 =正在增长

2 个答案:

答案 0 :(得分:2)

我没有看到'x'的声明,但是假设它是char *。在线

    word_array[i] = x;

您没有将字符串复制到表中,只是将第一个char *设置为指向x。解决方案是使用strcpy或类似的,可能是这样的:

    strcpy(word_array[i], x);

答案 1 :(得分:2)

此代码有多个问题,包括:

  • 忽略realloc()
  • 的返回值
  • 假设固定的50-char缓冲区可以容纳150个字符宽的字符串(包括终结符)。
  • 忽略每个单词的内存分配(泄漏),只需将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);
}