C fread只在我第一次运行程序时才开始阅读
当我第一次跑步时,我会添加3条记录,这给了我3条记录的计数。然后我将计数写入bin文件,将记录写入bin文件,然后关闭程序 当我重新打开它,然后我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
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:
$