读一个C文件,读一个额外的行,为什么?

时间:2012-04-13 13:02:57

标签: c

我不确切地知道为什么文件指针从文件读取额外的行,特别是最后一行,这里是代码:

FILE *fp ;
fp = fopen ("mac_ip.txt", "r") ;
int mac;
char *ip = (char *) malloc(15);

while(!feof(fp)){
    fscanf(fp,"%i",&mac);
    fscanf(fp,"%s",ip);

    printf("MAC: %i\n",mac);
    printf("IP: %s\n",ip);  
}

并且文件正好有20行,但是第20行打印了两次。

哪个错误?

提前致谢。

6 个答案:

答案 0 :(得分:6)

因为在阅读了最后两个值之后,你仍然没有点击EOF。所以循环继续。在循环的下一次传递中,fscanf实际上不会像第二次一样读取最后一行,fscanfs会失败,但是printfs会打印出循环上一次传递的值。

答案 1 :(得分:5)

feof在您尝试阅读更多内容之前,不会“知道”它在文件末尾。由于fscanf告诉你它有多少项,你可以使用这个简单的技巧:

for(;;){
    if (fscanf(fp,"%i%s", &mac, ip) != 2) break;
    printf("MAC: %i\n",mac);
    printf("IP: %s\n",ip);  
}

答案 2 :(得分:2)

在第二十行完成两次读取后,你必须到文件的末尾,但系统不知道这一点。 feof只会在你试图越过文件末尾时触发,而不是在你正好在它上面时...

此外,您可能在第20行有一个行尾(CR或CR-LF),它只会在另一次尝试读取时通过。

解决方案是一次性读取行(对此有一个特定的C命令),然后解析它以获取数据。如果整行读取失败,那么你已经到了最后。

答案 3 :(得分:1)

您的代码类似于以下示例

#include <stdio.h>

int main(void)
{
    char buffer[256];
    FILE * myfile;

    myfile = fopen("some.txt","r");

    while (!feof(myfile))
    {
        fgets(buffer,256,myfile);
        printf("%s",buffer);
    }

    fclose(myfile);

    return 0;
}

http://www.friedspace.com/feof.html

答案 4 :(得分:0)

您最好在打印结果前测试fscanf返回值。我敢打赌,在循环的最后一次迭代中,fscanf调用失败并打印最后返回的结果。

答案 5 :(得分:0)

FILE *fp ;
int mac;
char ip[15];

fp = fopen ("mac_ip.txt", "r") ;
if (!fp) return;

while(1){
    if (fscanf(fp,"%i",&mac) < 1) break;
    if (fscanf(fp,"%s",ip) < 1) break;

    printf("MAC: %i\n",mac);
    printf("IP: %s\n",ip);  
}
fclose (fp);

fscanf()返回它疯狂的分配数(或eof上的-1)。通过使用返回值,您不需要eof()函数。 BTW我认为你不能将MAC地址读入int。也许你需要把它读成一个字符串?

说明:feof()不执行OP期望的操作。 feof()只应在其中一个文件操作失败后进行检查。在大多数情况下,您不需要feof()。