"fgets" 在 while 循环中的意外行为

Unexpected behavior from "fgets" in a while loop

我正在尝试使用 fgets 逐行读取文件,但它不起作用。这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_LINE_SIZE 500
int main(int argc, char const *argv[])
{
    char *line;
    FILE *arq;


    //abre o arquivo para leitura
    if ((arq = fopen (argv[1], "r")) == NULL){
            printf ("erro ao abrir arquivo\n");
            exit (1);
    } 

    //aloca espaco para a linha
    if ((line = (char*) calloc (MAX_LINE_SIZE, sizeof(char))) == NULL){
            printf ("erro ao alocar memoria\n");
            exit (1);
    }

    //para cada linha
    while (fgets (line, MAX_LINE_SIZE, arq) != NULL){
            printf ("%s\n", line);
    }

    //desaloca a memoria
    free (line);

    //fecha o arquivo
    fclose (arq);

    return 0;
}

如果我的输入文件的第一行短于 MAX_LINE_SIZE 中指定的大小,在同一交互中,fgets 开始用第二行的内容覆盖第一行的内容。例如,将 MAX_LINE_SIZE = 14 与此输入文本一起使用:

AAAAAAA 
BBBBBBBBBB

我得到这个输出:

Gabriels-MacBook-Air:Desktop Gabriel$ make
gcc teste.c;./a.out input.txt
BBBBBAA
BBBBB

我认为fgets方法是识别换行符,然后,它将写入指针移动到字符串的开头并继续读取直到到达MAX_INE_SIZE。但为什么?有人可以帮我吗?谢谢!

也许您的文件包含与您的平台不匹配的行尾?如果您的文件使用 CR 作为行尾(旧 MacOS)并且您 运行 在类 Unix 平台上这样做,您会得到这种行为。

代码编译正常,定义为 MAX_LINE_SIZE = 14。我尝试了几种不同的方法来获取输出,唯一可行的方法是替换你的 space 字符用 ^M 输入 "AAAAAAA BBBBBBBBBB"。所以您可能想查看您的输入文件并查看其中是否有 ^M。 ^M 是 ASCII 13,它是一个马车 return.

除此之外,代码使用 clang 在 FreeBSD 机器上编译。正如有人提到的那样,强烈建议不要转换 malloc、realloc、calloc 和其他内存分配函数的结果。也不需要它,因为 void* 与所有指针类型兼容。

另外。我必须将以下行添加到测试程序的顶部以获得带有 1 个警告的编译:

#include <stdio.h>
#include <stdlib.h>

#define MAX_LINE_SIZE 14

所以你的代码确实有效,我相信问题出在输入中。