【问题标题】:Can't scan in .txt file using fgets into flexible data structure无法使用 fget 将 .txt 文件扫描到灵活的数据结构中
【发布时间】:2019-05-20 14:45:03
【问题描述】:

我有一个家庭作业,需要我处理 .txt 文件,方法是将它们扫描成一个灵活的数据结构,然后在文件中搜索带有大写字母的单词。我在使用我正在使用的这种灵活的数据结构中扫描它们时遇到问题。数据结构需要灵活的原因是它需要能够处理任何 .txt 文件。

我要使用的数据结构是一个数组,它指向包含该行内容的数组。如果更容易,我愿意使用不同的结构。

我尝试使用 fgets 逐行扫描它,并使用 malloc 分配刚好足以存储该行,但它似乎不起作用。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STEPSIZE 100

int main()
{
    FILE *inputFile;

    //Opens the file in read mode
    inputFile = fopen("testfile.txt", "r");

    //Error message if file cannot open
    if (inputFile == NULL)
    {
        printf("Unable to open file");
        return 1;
    }

    int arrayLen = STEPSIZE;

    // Allocate space for 100 lines. The **lines is the data structure used to store all the lines

    char **lines = (char **)malloc(STEPSIZE * sizeof(char*));

    char buffer[3000];

    int i = 0;

    while (fgets(buffer, 3000, inputFile))
    {

        //Checks if the array is full, and extends it
        if(i == arrayLen)
        {
            arrayLen += arrayLen;
            char ** newLines = realloc(lines, 200 * sizeof(char*));
            if(!newLines)
            {
                printf("cant realloc\n");
            }
            lines= newLines;
        }


        // Get length of buffer
        int lengthOfBuffer = strlen(buffer);

        //Allocate space for string. The +1 is for the terminating character
        char *string = (char *)malloc((lengthOfBuffer + 1) * sizeof(char));

        //copy string from buffer to string
        strcpy(string, buffer);

        //Attach string to data structure
        lines[i] = string;

        //Increment counter
        i++;
        printf("%s", lines[i]);
    }

    //Closes the file
    fclose(inputFile);


    for (int j = 0; j < 100; j++){
        printf("%s \n", lines[i]);
    }

    return 0;
}

当最终的 for 循环运行时,理想情况下会打印文件的内容,以表明它已被存储并且能够被处理,但目前我得到退出代码 11。

任何帮助将不胜感激。

【问题讨论】:

  • 如果文件中只有 12 行,尝试打印第 96 行会发生什么?
  • 为什么不直接获取文件的大小,然后在读取文件之前为其分配所需的内存?看这里:stackoverflow.com/questions/238603/… 一旦你有了文件的大小,然后调用 malloc 并读入缓冲区。而且您的代码没有释放任何分配的内存。
  • 这段代码到处都有神奇的常量
  • @Nina 这可能是一种锻炼,他必须这样做。

标签: c malloc fgets


【解决方案1】:

这里有个问题:

//Increment counter
i++;
printf("%s", lines[i]);    // you're printing the next file that does not yet exist

正确代码:

printf("%s", lines[i]);
//Increment counter
i++;

这里还有一个:

for (int j = 0; j < 100; j++) {  // your loop variable is j
  printf("%s \n", lines[i]);     // but you use i here.
}

正确代码:

for (int i = 0; i < 100; i++) {
  printf("%s \n", lines[i]);
}

这里还有一个:

  arrayLen += arrayLen;
  char ** newLines = (char**)realloc(lines, 200 * sizeof(char*));
  // here the new length of your array is inconditionally 200
  // but actually the new array length is arrayLen 

正确代码:

  arrayLen += arrayLen;
  char ** newLines = (char**)realloc(lines, arrayLen * sizeof(char*));

可能还有更多问题,我没有检查所有内容。

顺便说一句:sizeof(char) 的定义是 1,所以你可以放弃它。

BTW2:arrayLen += arrayLen; 你确定这是你想要的吗?每次都将数组的大小加倍。这不一定是错误的,但是使用这种方法,数组长度会很快增长到一个很大的数字。你可能想要这个:arrayLen += STEPSIZE;

顺便说一句:

while (fgets(buffer, 3000, inputFile))

这实际上并没有错,但你最好这样写:

while (fgets(buffer, sizeof buffer, inputFile))

这消除了两个硬编码常量之一3000

BTW4:最后你只打印你读过的前 100 行。您应该能够自己更正。

BTW5:您还应该释放您分配的所有内存。我把这个作为练习留给你。提示:在main末尾添加大约三行代码。

【讨论】:

  • @jzpearson 复制/过去可能很危险。
  • 没有内存释放@Jabberwocky
  • @Jabberwocky 谢谢你的帮助。我真的很感激这些变化。我在搜索带有大写字母的单词时遇到问题,我可以将我写的内容发给你吗?
  • @jzpearson 不,你不能,请在这个网站上问另一个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-25
相关资源
最近更新 更多