stdin 在一线后到达 EOF

stdin reaching EOF after first line

提问人: 提问时间:7/9/2019 最后编辑:chqrlie 更新时间:7/9/2019 访问量:213

问:

我正在尝试使用 .我正在阅读它:type file.txt | myprogram.exe

char *line;
struct block *newblock, *cur;
int i, osl, cbs, rs;
int startblock;

/* read in the blocks ... */
while (!feof(stdin) && !ferror(stdin)) {
    cbs = 2048;
    line = (char *)malloc(cbs + 1);
    if (!line) {
        perror("malloc");
        exit(1);
    }
    line[cbs] = '\0';

    /* read in the line */
    if (!fgets(line, cbs, stdin)) {
        free(line);
        continue;
    } else {
        while (line[cbs - 2]) {
            /* expand the line */
            line = (char *)realloc(line, (cbs * 2) + 1);
            if (!line) {
                perror("realloc");
                exit(1);
            }
            line[cbs * 2] = '\0';

            /* read more */
            if (!fgets(line + cbs - 1, cbs + 1, stdin))
                break;

            cbs *= 2;
        }
    }
    ...
}

但是在读取第一行之后,即使文件中有多行,也会返回 true。怎么会这样呢?feof()

c std stdin fgets eof

评论

1赞 Some programmer dude 7/9/2019
请花一些时间阅读为什么“while (!feof(file))”总是错的?
0赞 Weather Vane 7/9/2019
看起来可以读取内部循环中的整个文件,因为它正在检查哪些是未初始化的内存。while (line[cbs - 2])
0赞 Some programmer dude 7/9/2019
至于你的算法,这似乎是完全错误的。如果你想在不知道其确切长度的情况下阅读一行,那么使用(就像你正在做的那样),但检查字符串是否以换行符结尾。如果末尾没有换行符,则要读取更多行。使用 或 找出末尾是否有换行符(字符串,可能不是数组的末尾!fgetsstrchrstrcspn

答:

1赞 chqrlie 7/9/2019 #1

该代码存在多个问题:

  • 文件末尾测试不正确:仅在读取函数失败提供有意义的信息。feof()
  • 重新分配方案被破坏:您测试数组的倒数第二个字节,但如果该行较短,则可能没有设置此字节。fgets()

以下是修复程序的方法:

  • 如果您的系统支持它,则使用它。 分配足够大的缓冲区,以便一次读取一整行。getline()getline()
  • 或用于读取行片段并检查它是否以换行符结尾。fgets