【发布时间】:2016-06-29 10:19:54
【问题描述】:
此代码从二进制文件读取/写入数据。这里modify() 将接受用户的输入,在文件中搜索它。如果找到,将提示用户提供新条目,旧条目将被替换。
问题是,在modify() fwrite() 之后,如果我在break while 循环中,那么一切都会好起来的,但如果我不这样做,那么条目仍然会被修改,但内容也会随之修改的文件会被复制,为什么会这样?
与开头一样,文件中没有重复的条目。 所以我期望的是,即使我不使用break,循环也应该继续并最终在读取整个文件时终止。在这里,if(strcmp(e.name,user)==0) 仅对一个条目为真,因此控件应在此 if 块中只输入一次。那么这些条目是如何重复的呢?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void add(FILE *);
void list(FILE *);
void modify(FILE *);
struct emp
{
char name[20];
int id;
float sal;
}e;
void add(FILE *f)
{
char *p=NULL;
printf("\nEnter name id sal\n");
scanf(" %s %d %f", e.name,&e.id,&e.sal);
fseek(f,0,SEEK_END);
if((fwrite(&e,sizeof(struct emp),1,f))==1)
{
printf("\nAdded Successfully\n");
}
else
{
printf("\nError wrting to file in ADD func\n");
}
}
void list(FILE *f)
{
rewind(f);
while(fread(&e,sizeof(struct emp),1,f)>0)
{
printf("\nRead %s %d %f\n",e.name,e.id,e.sal);
}
}
void modify(FILE *f)
{
char user[20];
char *p=NULL;
printf("\nEnter name to modify\n");
scanf(" %s", user);
rewind(f);
while(fread(&e,sizeof(struct emp),1,f)==1)
{
//printf("\n --------------- %s %d %f\n",e.name,e.id,e.sal);
if(strcmp(e.name,user)==0)
{
//fseek(f,-sizeof(struct emp),SEEK_CUR);
printf("\nEnter new name id salary\n");
scanf(" %s %d %f", e.name,&e.id,&e.sal);
fseek(f,-sizeof(struct emp),SEEK_CUR);
if(fwrite(&e,sizeof(struct emp),1,f)==1)
{
printf("\nModified successfull!!\n");
//break;
}
else
{
printf("\nError while modifying\n");
}
}
else
{
printf("\n\nstring not matched\n\n");
}
}
}
int main()
{
char val='T';
FILE *fp=NULL;
if((fp=fopen("database.dat","rb+"))==NULL)
{
if((fp=fopen("database.dat","wb+"))==NULL)
{
printf("\nError opening file in wb+ mode\n");
exit(0);
}
}
do
{
printf("\nEnter a to add, l to list, d to delete, m to modify and e to exit\n");
scanf(" %c", &val);
switch(val)
{
case 'a':
add(fp);
break;
case 'l':
list(fp);
break;
case 'm':
modify(fp);
break;
case 'd':
// del(fp);
break;
case 'e':
fclose(fp);
exit(0);
break;
default:
printf("\nInvalid Input\n");
break;
}
}
while(1);
}
【问题讨论】:
-
一旦你调用了未定义的行为,任何事情都可能发生。
fflush(stdin)确实会调用未定义的行为。在此处询问之前,请删除所有已知的未定义行为案例。由于您似乎并不真正了解未定义行为的含义,因此请了解一下! -
@Olaf 删除了所有出现的
fflush(stdin)。请立即检查。