在二进制文件C中编辑记录
我正在做一个C项目,关于二进制文件中记录的CRUD操作。 记录使用的是结构数据类型 我在更新记录时遇到问题。以下是函数:在二进制文件C中编辑记录,c,structure,binaryfiles,C,Structure,Binaryfiles,我正在做一个C项目,关于二进制文件中记录的CRUD操作。 记录使用的是结构数据类型 我在更新记录时遇到问题。以下是函数: void modifyGoods(char fileName[]) { struct myGood newGood; int idNumber, found = 0; printf("\nUPDATING THE RECORD..."); printf("\nEnter the id of the re
void modifyGoods(char fileName[]) {
struct myGood newGood;
int idNumber, found = 0;
printf("\nUPDATING THE RECORD...");
printf("\nEnter the id of the record you would like to update: ");
scanf("%d", &idNumber);
FILE* filePointer = fopen(fileName, "rb+");
while ((fread(&newGood, sizeof(newGood), 1, filePointer)) > 0 && found == 0) {
if (newGood.id == idNumber) {
// new data of the record
printf("\nEnter the new data:\n");
printf("Category: ");
scanf("%s", &newGood.category);
printf("Description: ");
scanf("%s", &newGood.description);
printf("Price: ");
scanf("%f", &newGood.price);
printf("Quantity: ");
scanf("%d", &newGood.quantity);
// go one record back in order to overwrite the record that needs to be updated
fseek(filePointer, -(long)sizeof(newGood), SEEK_CUR);
//overwrites record
fwrite(&newGood, sizeof(newGood), 1, filePointer);
printf("Record updated!\n");
found = 1;
printf("%d", found);
}
}
fclose(filePointer);
if (found == 0) {
printf("\nERROR! THIS ID DOESN'T EXIST!\n\n");
}
}
如果我更新二进制文件的第一条记录,它将按预期工作,但如果我尝试更新第一条记录之后的任何记录,则会发生以下情况:
A B C-二进制文件中的记录
如果我尝试更新B,那么它将变成:A B(更新的)B(旧记录)
记录得到更新,但他之后的记录被第二个记录的旧值覆盖
我应该如何处理这个问题?我更改了fseek函数的偏移量,但仍然不起作用
谢谢,,
马可首先
你怎么知道scanf成功了?如果用户刚刚按下enter键,您是否愿意接受定义时出现在idNumber
中的任何值
测试每个返回代码。唯一可以安全忽略的是关闭文件时。(这几乎从未发生过,如果发生了,你能做什么?)
我不确定你的程序出了什么问题,但我有两个建议可能会有所帮助
for
循环来添加ftell:
size_t len;
for( off_t pos=ftell(filePointer);
(len = fread(&newGood, sizeof(newGood), 1, filePointer)) == sizeof(newGood;
pos=ftell(filePointer) ) {
...
if( -1 == fseek(filePointer, pos, SEEK_SET) ) {
err(EXIT_FAILURE, "could not seek");
}
if (newGood.id != idNumber) {
continue;
}
//overwrites record
if( sizeof(newGood) != fwrite(&newGood, sizeof(newGood), 1, filePointer) ) {
err(EXIT_FAILURE, "could not write");
}
printf("Record updated!\n");
found = 1;
printf("%d", found);
break;
}
还有一点:当退出循环时,假设find为0,则未找到记录fread(3)会在出错时返回0,导致循环退出,在这种情况下,告诉用户记录不在那里会有点误导。只有当
fseek()
失败时才会发生这种情况。我不知道除此之外还会发生什么,但您将以这种方式读取两条记录。在第一个循环之后,它将首先再次读取,然后停止,因为找到了!=0.@EmanuelPfound==0
意味着继续,而不是停止。切换while循环的条件以避免额外的fread()
——现在它在检查found
之前执行读取,因此在found
更改后执行一次额外读取,即使它不再进入循环体。不过,这可能是无害的,因为在额外读取之后,您所做的就是关闭文件。
size_t len;
for( off_t pos=ftell(filePointer);
(len = fread(&newGood, sizeof(newGood), 1, filePointer)) == sizeof(newGood;
pos=ftell(filePointer) ) {
...
if( -1 == fseek(filePointer, pos, SEEK_SET) ) {
err(EXIT_FAILURE, "could not seek");
}
if (newGood.id != idNumber) {
continue;
}
//overwrites record
if( sizeof(newGood) != fwrite(&newGood, sizeof(newGood), 1, filePointer) ) {
err(EXIT_FAILURE, "could not write");
}
printf("Record updated!\n");
found = 1;
printf("%d", found);
break;
}