C - 在二进制文件中修改记录,输出为文本文件将0s插入文本文件
我的C文件中有三个函数用于二进制文件:accadd用于添加记录,用于在文本文件中查看输出并修改用于修改记录。C - 在二进制文件中修改记录,输出为文本文件将0s插入文本文件
A记录的结构如下:
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;
视图功能犯规输出所有的变量,只有名称,登录号和电话。例如,对于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;
}
一些可变印刷后,我设法承担我被卡在写入模式和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);
}
我希望对任何想要从二进制文件修改记录的人都有用。
我最好的猜测是,你的fread()方法以某种方式行为不端。要进行调试,您可能需要捕获返回值,以便在调试器中进行检查。因此,更改视图()函数做这样的事情:
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条记录时应该具有的值。
问题在于修改功能。如果在第一篇文章(选择选项1)中添加2条记录,其中一条电话= 777777777,另一条没有,然后使用选项2打印它,则会得到文件output.txt。这个文件很好,输出很好,文件中只有2条记录。但是当你修改它的时候,你会在文件中得到那些奇怪的输入。 – RaresD
什么是'add'?它在哪里宣布? –
请查看第一个代码块,我在那里定义了结构。 – RaresD
啊我看到了,它是定义结构时定义的全局。这里不需要全局变量,建议在函数内定义变量。 –