将struct对象输出到二进制文件,并在C中从中输入

将struct对象输出到二进制文件,并在C中从中输入,c,binary,feof,C,Binary,Feof,我用C写管理系统。 我有这个结构 #define STRING_LENGTH 32 typedef struct { char name[STRING_LENGTH]; } Name; typedef struct{ int id, balance; Name clientName; } Client; 我创建了一些测试对象,打开二进制文件进行写入,使用fwrite将对象写入文件,关闭它,然后使用fread将其写入while(!feof…块),我的问题是我将4个对象打

我用C写管理系统。 我有这个结构

#define STRING_LENGTH 32
typedef struct {
    char name[STRING_LENGTH];
} Name;

typedef struct{
    int id, balance;
    Name clientName;
} Client;
我创建了一些测试对象,打开二进制文件进行写入,使用
fwrite
将对象写入文件,关闭它,然后使用
fread
将其写入
while(!feof…
块),我的问题是我将4个对象打印到二进制文件中,当我从文件中读取对象并将其打印到屏幕上时,最后一个对象打印了两次。 我做的不对吗?我只需要将对象写入文件,然后从文件中取回它们

我的代码:

FILE *clientsFile = NULL;

switch (selectedOption)
{
case CLIENT:

        clientsFile = fopen(CLIENTS_FILE_PATH, "wb");

        Client getUser;
        Client temp1 = { 1, 10000, "Alex" };
        Client temp2 = { 2, 100000, "Valery" };
        Client temp3 = { 3, 105466, "Jack" };
        Client temp4 = { 4, 1069640, "Pam" };

        fwrite(&temp1, sizeof(Client), 1, clientsFile);
        fwrite(&temp2, sizeof(Client), 1, clientsFile);
        fwrite(&temp3, sizeof(Client), 1, clientsFile);
        fwrite(&temp4, sizeof(Client), 1, clientsFile);

        fclose(clientsFile);

        clientsFile = fopen(CLIENTS_FILE_PATH, "rb");

        do
        {               
            fread(&getUser, sizeof(Client), 1, clientsFile);
            printf("ID : %d, Name : %s, Balance : %d\n", getUser.id, getUser.clientName.name, getUser.balance);
        } while (!feof(clientsFile));

        break;
输出照片:

感谢您的回答

feof()
如果文件结束指示符标志被提升,则返回true。成功调用
fread()
不会导致提升标志。因此,在读取最后一条记录后,您将再次迭代一次

相反,检查
fread()
是否成功,以确定是否已到达文件末尾或遇到其他错误

    do
    {               
        if (fread(&getUser, sizeof(Client), 1, clientsFile) == 1) {
            printf("ID : %d, Name : %s, Balance : %d\n", getUser.id, getUser.clientName.name, getUser.balance);
        } else {
            /* do something */
        }
    } while (!feof(clientsFile));

这是因为您正在使用do while

do
{               
    fread(&getUser, sizeof(Client), 1, clientsFile);
    printf("ID : %d, Name : %s, Balance : %d\n", getUser.id, getUser.clientName.name, getUser.balance);
} while (!feof(clientsFile));
在本例中,当您第五次读取时,您会得到EOF。但是“getUser”仍然有第四个客户端条目。因此,您会得到最后两次输出

解决方案: 将其更改为while循环

while (fread(&getUser, sizeof(Client), 1, clientsFile) && !feof(clientsFile))
{
    printf("ID : %d, Name : %s, Balance : %d\n", getUser.id, getUser.clientName.name, getUser.balance);
}

我的方法是这样做。如果你读取了正确数量的记录,很好,如果没有,就退出。没有必要涉及
feof()


如果调用fread()时发生错误会发生什么情况?AFAICT,feof()将返回0,程序将陷入一个永恒的循环中,对吗?不是很优雅,因为在两个不同的地方有完全相同的
fread
。比约纳和迈克尔,我同意这两点。谢谢。我更新了我的答案。现在可以了吗?
while(fread(&getUser, sizeof(Client), 1, clientsFile) == 1) {
    printf("ID : %d, Name : %s, Balance : %d\n", getUser.id, getUser.clientName.name, getUser.balance);
}