来自while循环中“fgets”的意外行为

时间:2015-06-04 19:19:45

标签: c macos while-loop fgets

我正在尝试使用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。但为什么?有人能帮助我吗?谢谢!

2 个答案:

答案 0 :(得分:0)

也许您的文件的行尾不符合您的平台?如果您的文件使用CR作为行结尾(旧MacOS)并且您在类Unix平台上运行它,则会出现此行为。

答案 1 :(得分:0)

通常使用MAX_LINE_SIZE = 14的定义编译代码。我尝试了几种不同的输出方式,唯一可行的方法是替换输入中的空格char&#34; AAAAAAA BBBBBBBBBB&#34;用^ M。因此,您可能需要查看输入文件并查看其中是否包含^ M. ^ M是ASCII 13,这是一个回车。

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

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

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

#define MAX_LINE_SIZE 14

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