我的C文件中有3个函数用于二进制文件:accadd用于添加记录,视图用于输出文本文件,修改用于修改记录。
记录具有以下结构:
struct date
{
int day;
int month;
int year;
};
struct customer
{
char name[40], acctype[10];
int accno, age;
double phone;
float amount;
struct date deposit;
} add;
视图功能不输出所有变量,只输出name,accno和phone。例如,添加了2个记录,这是输出文件:
Customer's List
Customer's Name: Account Number: Customer's Phone No:
John 1 777777777
Mary 2 111111111
这很好,除非我运行修改功能并再次输出文件:
Customer's List
Customer's Name: Account Number: Customer's Phone No:
John 1 999999999
Mary 2 111111111
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
记录被修改但我得到了一堆领先的0。有什么理由吗?
修改功能:
void modify(char file[30]){
FILE *view;
int counter = 0;
view = fopen(file, "rb+");
if (view == NULL)
exit(1);
while (fread(&add, sizeof(add), 1, view) != 0)
{
if(add.phone==777777777){
printf("Old phone is: %lf\n",add.phone);
printf("New phone:\n");
scanf("%lf", &add.phone);
printf("New phone is: %lf\n",add.phone);
fseek(view,sizeof(add)*counter,SEEK_SET);
fwrite(&add,sizeof(add),1,view);
}
counter++;
}
fclose(view);
if (counter == 0)
{
printf("NO RECORDS FOUND!\n");
}
else{
printf("add.phone printed\n");
}
}
EDIT1:视图功能。
void view(char file[30])
{
FILE *view,*output;
int test = 0;
output=fopen("output.txt", "w");
fprintf(output,"Customer's List\n");
fprintf(output,"\tCustomer's Name:");
fprintf(output,"\tAccount Number:");
fprintf(output,"\tCustomer's Phone No:\n");
view = fopen(file, "rb");
if (view == NULL)
exit(1);
while (fread(&add, sizeof(add), 1, view) != 0)
{
fprintf(output,"\t%16s", add.name);
fprintf(output,"\t%15d", add.accno);
fprintf(output,"\t%20.0f", add.phone);
fprintf(output,"\n");
test++;
}
fclose(view);
fclose(output);
if (test == 0)
{
printf("NO RECORDS FOUND!\n");
}
else{
printf("Output updated in file output.txt\n");
}
}
EDIT2:MCVE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void menu(void);
void accadd(void);
void modify(char file[30]);
void view(char file[30]);
struct date
{
int day;
int month;
int year;
};
struct customer
{
char name[40], acctype[10];
int accno, age;
double phone;
float amount;
struct date deposit;
} add;
void accadd(void)
{
FILE *fp = fopen("cus.dat", "ab+");
if (fp == NULL)
exit(1);
printf("ADD RECORD\n");
printf("Enter today's date(date/month/year) \n");
if (scanf("%d/%d/%d", &add.deposit.day, &add.deposit.month, &add.deposit.year) != 3)
exit(1);
printf("Enter account number\n");
if (scanf("%d", &add.accno) != 1)
exit(1);
printf("Enter customer's name\n");
if (scanf("%s", add.name) != 1)
exit(1);
printf("Enter customer's age\n");
if (scanf("%d", &add.age) != 1)
exit(1);
printf("Enter customer's phone num\n");
if (scanf("%lf", &add.phone) != 1)
exit(1);
printf("Enter the account type(in words): \n\t 1:Current\n\t 2:Saving\n\t 3:Fixed\n");
if (scanf("%s", add.acctype) != 1)
exit(1);
printf("Almost done! Just enter the amount you want to deposit: ");
if (scanf("%f", &add.amount) != 1)
exit(1);
fwrite(&add, sizeof(add), 1, fp);
fclose(fp);
}
void view(char file[30])
{
FILE *view,*output;
int test = 0;
output=fopen("output.txt", "w");
fprintf(output,"Customer's List\n");
fprintf(output,"\tCustomer's Name:");
fprintf(output,"\tAccount Number:");
fprintf(output,"\tCustomer's Phone No:\n");
view = fopen(file, "rb");
if (view == NULL)
exit(1);
while (fread(&add, sizeof(add), 1, view) != 0)
{
fprintf(output,"\t%16s", add.name);
fprintf(output,"\t%15d", add.accno);
fprintf(output,"\t%20.0f", add.phone);
fprintf(output,"\n");
test++;
}
fclose(view);
fclose(output);
if (test == 0)
{
printf("NO RECORDS FOUND!\n");
}
else{
printf("Output updated in file output.txt\n");
}
}
void modify(char file[30]){
FILE *view;
int counter = 0;
view = fopen(file, "rb+");
if (view == NULL)
exit(1);
while (fread(&add, sizeof(add), 1, view) != 0)
{
if(add.phone==777777777){
printf("Old phone is: %lf\n",add.phone);
printf("New phone:\n");
scanf("%lf", &add.phone);
printf("New phone is: %lf\n",add.phone);
fseek(view,sizeof(add)*counter,SEEK_SET);
fwrite(&add,sizeof(add),1,view);
}
counter++;
}
fclose(view);
if (counter == 0)
{
printf("NO RECORDS FOUND!\n");
}
else{
printf("add.phone printed: %i\n",counter);
printf("add length %d\n",sizeof(add));
}
}
void menu(void)
{
int n,account_number;
char file[30],account_name[30];
printf("Enter your choice 1, 2, 3\n");
while(1){
if (scanf("%d", &n) != 1)
exit(1);
switch (n){
case 1:
accadd();
break;
case 2:
printf("Enter the file\n");
scanf("%s",&account_name);
view(account_name);
break;
case 3:
modify("cus.dat");
break;
}
printf("Enter your choice 1, 2, 3\n");
}
}
int main(void)
{
menu();
return 0;
}
答案 0 :(得分:1)
经过一些更多的变量打印之后,我设法假设在fwrite之后我陷入了写作模式,所以我使用了
fseek(f,0,SEEK_SET);
返回阅读模式。我不知道这个解释是否准确,但它解决了我的问题。
我还将我的修改功能简化为更清晰。
void modify(char file[30]){
FILE *view;
int counter = 0;
view = fopen(file, "rb+");
if (view == NULL)
exit(1);
while (fread(&add, sizeof(add), 1, view) != 0)
{
if(add.phone==777777777){
add.phone=145;
fseek(view,sizeof(add)*counter,SEEK_SET);
fwrite(&add,sizeof(add),1,view);
fseek(view,0,SEEK_SET);
}
counter++;
}
fclose(view);
}
我希望对任何想要修改二进制文件记录的人都有用。
答案 1 :(得分:0)
我最好的猜测是你的fread()方法在某种程度上行为不端。要调试它,您可能需要捕获返回值,以便在调试器中轻松检查。因此,请将view()函数更改为:
void view(char file[30])
{
FILE *view,*output;
size_t ret;
int test = 0;
/* ... */
while ((ret = fread(&add, sizeof(add), 1, view)) != 0)
{
fprintf(output,"\t%16s", add.name);
fprintf(output,"\t%15d", add.accno);
fprintf(output,"\t%20.0f", add.phone);
fprintf(output,"\n");
test++;
}
fclose(view);
fclose(output);
/* ... */
}
在调试器中,在循环的第一行设置断点,并在每次迭代中检查ret变量。对于两个预期的迭代,ret的值应该是1,但是对于打印零的迭代,它是什么?
一种可能性是,它在某些情况下选择通过返回-1来表示错误(是的,那将被打破)。在这种情况下,您可以将条件从非零测试更改为测试fread()在读取1条记录时应具有的实际返回值。