C fread只在我第一次运行程序时才开始阅读

C fread只在我第一次运行程序时才开始阅读,c,arrays,struct,fwrite,fread,C,Arrays,Struct,Fwrite,Fread,当我第一次跑步时,我会添加3条记录,这给了我3条记录的计数。然后我将计数写入bin文件,将记录写入bin文件,然后关闭程序 当我重新打开它,然后我freadin,它会给我3条记录和3个计数。但从那以后,无论我备份还是读入,它都会给我相同的计数3和3记录,尽管由于计数也没有更新,这可能就是为什么fread只读取第一次记录的原因 我不知道为什么计数器没有更新。fread和fwrite都返回=成功,所以我不确定发生了什么 void backUp(PAYROLL employee[], long int

当我第一次跑步时,我会添加3条记录,这给了我3条记录的计数。然后我将计数写入bin文件,将记录写入bin文件,然后关闭程序

当我重新打开它,然后我
fread
in,它会给我3条记录和3个计数。但从那以后,无论我备份还是读入,它都会给我相同的计数3和3记录,尽管由于计数也没有更新,这可能就是为什么
fread
只读取第一次记录的原因


我不知道为什么计数器没有更新。
fread
fwrite
都返回=成功,所以我不确定发生了什么

void backUp(PAYROLL employee[], long int *pCounter)
{
    FILE *counter;
        errno_t result1 = fopen_s(&counter, "c:\\myFiles\\counter.bin", "a+b");
        if (result1 == 0){
            fwrite(pCounter, sizeof(long int), 1, counter);
            fclose(counter);
        }
        else
            printf("Back up of counter failed! error:%d",result1);

    FILE *record;

        errno_t result2 = fopen_s(&record, "c:\\myFiles\\record.bin", "a+b");
        if (result2 == 0){
            fwrite(employee, *pCounter *sizeof(PAYROLL), 1, record);
            fclose(record);
        }

        else
            printf("Back up of record failed! error:%d", result2);
}

void upload(PAYROLL employee[], long int *pCounter)
{
    FILE *counter;
    errno_t result1 = fopen_s(&counter, "c:\\myFiles\\counter.bin", "a+b");
    if (result1 == 0){
        result = fread(pCounter, sizeof(long int), 1, counter);
        fclose(counter);
        printf("Counter:%d", *pCounter);
    }
    else
        printf("Upload up of counter failed!");
    FILE *record;
    errno_t result2 = fopen_s(&record, "c:\\myFiles\\record.bin", "r+b");
    if (result2 == 0)
    {

            result2 = fread(employee, *pCounter *sizeof(PAYROLL), 1, record);
            printf("Upload successful!\n");

        fclose(record);
    }
    else
        printf("Error opening file!");
}

我看到你的程序有很多错误

首先,将长整数和工资单结构直接写入文件。您永远不应该这样做,因为结构和整数具有依赖于机器的表示形式,如果您在一台机器(比如32位机器)上写入文件,然后在另一台机器(比如64位机器)上读取文件,那么您可能会遇到问题

其次,您没有检查fread()的返回值。应该经常检查

第三,将fread()的返回值赋给errno\u t。你确定你真的想这么做吗

如果你想得到实际问题的答案,请考虑更新源代码来修正我指出的错误,并考虑改进你的问题中的英语。此外,您应该提供一个完整的示例,即包含工资单定义的示例。当您知道fread()的实际返回值时,也许问题会更容易找到。

将最突出的注释转换为答案

:


当您没有检查它们的返回值时,如何知道
fread
fwrite
正在返回“success”

评论:

我查看了调试器并进入函数,结果是给我它们的成功返回值(如果它是这样工作的)

:

你仍然需要在程序中使用它。如果没有这种检查,您的代码将被一阵风吹倒

正确地说:


看起来在附加模式“a+b”中打开的任何地方,您都应该使用其他东西(“upload()中的“rb”和backUp()中的“wb”)

评论:

我不明白,有没有专门的错误检查功能?因为我一直认为错误检查只是查看结果值中的内容,然后我可以检查该值的含义是什么

查看和的规范 . 它们返回写入或读取的记录数,可能少于请求的记录数。如果您得到一个短写,那么您有一个问题-可能是磁盘空间不足。如果您得到一个简短的读取,可能是您请求了100条记录,但只有1条、10条或99条可读取(或者有错误)。如果不捕获并检查返回值,则不知道发生了什么

评论:

我看到它们读写1,但它仍然存储我的结构数组的前3个元素。我假设它是一个,因为它只是在写我的数组

fread()
(以及
fwrite()
)为您提供了相当大的灵活性,因为您可以分别提供项目的大小和数量。您使用:

result2 = fread(employee, *pCounter *sizeof(PAYROLL), 1, record);
这告诉
fread()
读取
1
大小
*pCounter*sizeof(工资单)
。您将获得
1
(成功)或
0
(失败)的结果。您可以指定:

result2 = fread(employee, sizeof(PAYROLL), *pCounter, record);
这将告诉您读取了多少条大小为
sizeof(PAYROLL)
的记录,最大值为
*pCounter
中的值。您可能会得到0或1或

下面是一些可操作的代码,它们或多或少地完成了所需的工作。
main()。我必须创建一个最低工资结构,因为问题没有提供

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

typedef struct PAYROLL
{
    long emp_id;
    char emp_name[32];
} PAYROLL;

static const char counter_bin[] = "counter.bin";
static const char records_bin[] = "records.bin";

static
void backUp(PAYROLL employee[], long int *pCounter)
{
    FILE *counter = fopen(counter_bin, "wb");
    if (counter != 0){
        fwrite(pCounter, sizeof(long int), 1, counter);
        fclose(counter);
    }
    else
        fprintf(stderr, "Back up of counter failed! error: %d %s\n", errno, strerror(errno));

    FILE *record = fopen(records_bin, "wb");
    if (record != 0){
        fwrite(employee, *pCounter *sizeof(PAYROLL), 1, record);
        fclose(record);
    }
    else
        fprintf(stderr, "Back up of records failed! error: %d %s\n", errno, strerror(errno));
}

static
void upload(PAYROLL employee[], long int *pCounter)
{
    FILE *counter = fopen(counter_bin, "rb");
    if (counter != 0){
        size_t result = fread(pCounter, sizeof(long int), 1, counter);
        fclose(counter);
        if (result != 0)
            printf("Counter: %ld\n", *pCounter);
        else
            fprintf(stderr, "Failed to read counter\n");
    }
    else
        fprintf(stderr, "Upload up of counter failed!\n");

    FILE *record = fopen(records_bin, "r+b");
    if (record != 0)
    {
        size_t result2 = fread(employee, *pCounter * sizeof(PAYROLL), 1, record);
        if (result2 == 1)
            printf("Upload successful!\n");
        else
            fprintf(stderr, "Failed to read records!\n");
        fclose(record);
    }
    else
        fprintf(stderr, "Error opening file!");
}

int main(void)
{
    PAYROLL emps[] =
    {
        { 1066, "William the Conqueror" },
        { 1819, "Victoria" },
        { 1689, "William and Mary" },
    };

    for (int i = 1; i <= 3; i++)
    {
        long emp_count = i;
        printf("Employee count = %ld\n", emp_count);
        backUp(emps, &emp_count);
        upload(emps, &emp_count);
        for (int j = 0; j < emp_count; j++)
            printf("%4ld: %s\n", emps[j].emp_id, emps[j].emp_name);
    }

    return 0;
}

odx
只是一个十六进制转储程序。选择你自己的程序,做一个同等的工作-
od-c
是一个后备方案,尽管我并不特别喜欢它的格式。)

你怎么知道
fread
fwrite
正在返回“成功”呢当您没有检查它们的返回值时?看起来像是在追加模式下打开的任何地方
“a+b”
,您可能应该使用其他东西(
上传()中的
“rb”
备份()中的
“wb”
查看和的规范。它们返回写入或读取的记录数,可能少于请求的记录数。如果您得到一个短写,那么您有一个问题-可能是磁盘空间不足。如果您得到一个简短的读取,可能是您请求了100条记录,但只有1条、10条或99条可读取(或者有错误)。如果你不捕获并检查返回值,你就不知道发生了什么。在你的提交中添加
result=fread…
是不公平的。正如@JonathanLeffler评论的那样,您需要将该
结果与您打算读取或写入的记录数进行比较。对于写入,检查写入是否成功。对于读取,这可能也不需要保存一个单独的文件来保存记录数。
fread()
(以及
fwrite()
)为您提供了相当大的灵活性,因为您可以分别提供项的大小和项的数量。您使用
result2=fread(员工,*pCounter*sizeof(工资单),1,记录)。这告诉
fread()
读取一个大小为
*pCounter*sizeof(工资单)
的项目。您将获得1(成功)或
$ Employee count = 1
Counter: 1
Upload successful!
1066: William the Conqueror
Employee count = 2
Counter: 2
Upload successful!
1066: William the Conqueror
1819: Victoria
Employee count = 3
Counter: 3
Upload successful!
1066: William the Conqueror
1819: Victoria
1689: William and Mary
$ odx counter.bin
0x0000: 03 00 00 00 00 00 00 00                           ........
0x0008:
$ odx records.bin
0x0000: 2A 04 00 00 00 00 00 00 57 69 6C 6C 69 61 6D 20   *.......William 
0x0010: 74 68 65 20 43 6F 6E 71 75 65 72 6F 72 00 00 00   the Conqueror...
0x0020: 00 00 00 00 00 00 00 00 1B 07 00 00 00 00 00 00   ................
0x0030: 56 69 63 74 6F 72 69 61 00 00 00 00 00 00 00 00   Victoria........
0x0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0x0050: 99 06 00 00 00 00 00 00 57 69 6C 6C 69 61 6D 20   ........William 
0x0060: 61 6E 64 20 4D 61 72 79 00 00 00 00 00 00 00 00   and Mary........
0x0070: 00 00 00 00 00 00 00 00                           ........
0x0078:
$