使用 feof 读取整个文件并打印结果给我双端

问题描述

我有,我正在尝试读取二进制文件直到结束并打印结果,我正在使用“feof”读取直到文件结束并打印每个结果,但我有一个问题是给我双重的最终结果。

我还在学习 C,所以我不知道为什么它给了我双重的最终结果,我尝试了很多方法,但这对我来说是最好的方法,也是最简单的,至少有效,但现在我'我在尝试修复它 2 小时后卡住了。

结果:

0
1
2
3
4
5
6
7
8
9
9

预期:

0
1
2
3
4
5
6
7
8
9

我的代码

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

int main()
{
    // https://www.aprendeaprogramar.com/cursos/verApartado.PHP?id=16007
    struct Datos
    {
        int cero;
        int uno;
        int dos;
        int tres;
        int cuatro;
        int cinco;
        int seis;
        int siete;
        int ocho;
        int nueve;
    };

    struct Datos datosEscrito = {0,1,2,3,4,5,6,7,8,9};

    FILE *fichero;

    fichero = fopen("tabla2.dat","wb");

    fwrite(&datosEscrito,sizeof(datosEscrito),fichero);

    fclose(fichero);

    int datoLeido;
    FILE *fichero2;

    fichero2 = fopen("tabla2.dat","rb");

    while (!feof(fichero2))
    {
        fread(&datoLeido,sizeof(datoLeido),fichero2);

        printf("%u",datoLeido);
        printf("\n");

    }

    fclose(fichero2);
}

PD:我不想要代码修复,我想了解为什么给我双端和自己修复错误方法,或其他方法来做同样的事情。感谢您的帮助。

代码编辑:

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

int main()
{

    FILE *fichero;

    fichero = fopen("tabla2.dat","wb");

    int count=0;

    while (count != 10)
    {
        fwrite(&count,sizeof(count),fichero);
        count++;
    }

    fclose(fichero);

    // PARTE LEER

    int datoLeido;
    FILE *fichero2;

    fichero2 = fopen("tabla2.dat","rb");

    while (!feof(fichero2))
    {

        fread(&datoLeido,datoLeido);
        printf("\n");

    }

    fclose(fichero2);

    return 0;
}

解决方法

您程序中的主要问题是 feof 只会在 previous fread(或其他读取操作)检测到结束时返回非零值 -文件条件,即使 fread 会通过其返回值告诉您它没有读取任何数据,您仍使用该值。

函数 feofferror 旨在区分 EOF 和 文件操作失败后的错误。

要修复读取循环,您可以使用例如

    do
    {
        /* we expect to read 1 member */
        if(fread(&datoLeido,sizeof(datoLeido),1,fichero2) == 1)
        {
            printf("%u",datoLeido);
            printf("\n");
        }
    } while ((!feof(fichero2)) && !ferror(fichero2));

您的代码中存在更多问题。

  • 格式 %u 对应于类型 unsigned int。对于 int,您应该使用 %d

  • 您将结构 struct Datos 的二进制表示写入文件,然后读回 int 类型的各个值。
    尽管这似乎在您的情况下产生了预期的结果,但在其他情况下可能不起作用。结构可以包含不属于任何结构字段的填充字节。这些将具有未定义的值。在任何情况下,写入/读取变量的二进制表示都取决于实现。当您使用不同的编译器(新版本、不同的操作系统、不同的 CPU...)甚至不同的编译器设置时,数据格式可能会发生变化。

,

我能够“修复”这个问题,但我认为这是一个肮脏的修复,但至少有效:

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

int main()
{

    FILE *fichero;

    fichero = fopen("tabla2.dat","wb");

    int count=0;

    while (count != 10)
    {
        fwrite(&count,sizeof(count),fichero);
        count++;
    }

    fclose(fichero);

    // PARTE LEER

    int datoLeido;
    FILE *fichero2;

    fichero2 = fopen("tabla2.dat","rb");

    while (!feof(fichero2))
    {
        fread(&datoLeido,fichero2);

        if(!feof(fichero2))
        {
            printf("%d",datoLeido);
            printf("\n");
        }
    }

    fclose(fichero2);

    return 0;
}

感谢所有人的帮助,@David Schwartz 在阅读后给了我提示,我不会在打印数据之前检查文件是否结束