当我第一次运行时,我会添加3条记录,这给我一个3的计数。然后我fwrite
计数到一个bin文件,并将记录转换成bin文件,然后我关闭程序。 / p>
当我重新打开它然后我fread
时,它会给我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!");
}
答案 0 :(得分:1)
我在你的程序中看到很多错误。
首先,您将长整数和PAYROLL结构直接写入文件。你永远不应该这样做,因为结构和整数具有依赖于机器的表示,如果你在一台机器上写文件(比如32位机器)并在另一台机器上读取它们(让我们说64位机器)那么你可能会遇到问题。
其次,您没有检查fread()的返回值。应该经常检查。
第三,您将fread()的返回值分配给errno_t。你确定你真的想这么做吗?
如果您想获得实际问题的答案,请考虑更新源代码以修复我指出的错误,并考虑改进您的问题中的英语。此外,您应该提供一个完整的示例,即包含PAYROLL定义的示例。当您知道fread()的实际返回值时,可能会更容易追踪问题。
答案 1 :(得分:1)
将最突出的评论转移到答案中。
您如何知道
fread
和fwrite
正在回归"成功"当你还没有检查他们的返回值时?
Jude评论道:
我查看调试器并进入函数,结果是给我成功返回值(如果它是如何工作的那样)。
你仍然需要在程序中。如果没有那种检查,你的代码就会被一阵风吹过。
看起来你在追加模式中打开的所有地方" a + b"你可能应该使用别的东西(" rb"在upload()和" wb"在backUp()中可能?)
Jude评论道:
我不明白,是否有特定的错误检查功能?因为我一直认为错误检查只是看结果的价值,然后我可以去检查一下这个值意味着什么?
查看fread()
的规范
fwrite()
。它们返回写入或读取的记录数,可能少于请求的数量。如果你得到一个简短的写,那么你有一个问题 - 可能没有磁盘空间。如果你得到一个简短的阅读,可能是你要求100条记录,但只有1或10或99可供阅读(或有错误)。如果您没有捕获并检查返回值,您就不知道发生了什么。
Jude评论道:
我看到他们读写1,但它仍然存储了我的struct数组的前3个元素。我认为它是一个因为它只编写我的数组?
fread()
(以及fwrite()
)为您提供了相当大的灵活性,因为您可以分别提供商品的尺寸和商品数量。你使用:
result2 = fread(employee, *pCounter *sizeof(PAYROLL), 1, record);
这会告诉fread()
阅读1
大小为*pCounter * sizeof(PAYROLL)
的项目。您将得到1
(成功)或0
(失败)的结果。你可以指定:
result2 = fread(employee, sizeof(PAYROLL), *pCounter, record);
会告诉您有多少大小为sizeof(PAYROLL)
的记录被读取,最多为*pCounter
中的值。你可能得到0或1或......
以下是一些可行的代码,可以或多或少地满足所需要的代码。 main()
程序演示了使用1,2和3个记录(名称是英格兰的几个国王和王后,以及他们提升到宝座的年份作为他们的雇员ID号)。我不得不创建一个最小的工资单结构,因为问题没有提供。
#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;
}
请注意,我已经考虑了文件名,因此您只需更改一行即可更改所使用的文件。样本输出:
$ 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:
$
(odx
只是一个十六进制转储程序。选择一个能完成同等工作的程序 - od -c
是一个后备,但我并不特别喜欢它的格式化。)