我需要你的帮助才能在c编程中进行顺序文件访问。 以下代码是我编写的代码的一部分。
我可以插入记录,搜索记录,显示所有记录 但是当它涉及修改和删除 我无法获得所需的结果。 在这种情况下,你可以指导我吗?
#include<stdio.h>
#include<stdlib.h>
int c,i,id;
char name[20];
FILE *fp;
int n;
int search(FILE *fp,int id);
void display(FILE *fp);
typedef struct details
{
int id;
char name[20];
}details;
details d;
void main()
{
printf("\nHow many records you would like to insert ? : ");
scanf("%d",&n);
fp=fopen("one.txt","a");
for(i=0;i<n;i++)
{
printf("\nEnter id and name");
scanf("%d%s",&d.id,d.name);
fwrite(&d,sizeof(d),1,fp);
}
fclose(fp);
while(1)
{
printf("\nWhat would you like to do now ? : \n");
printf("\n1.Display \t2.Search \t3.Modify \t4.Delete \t5.Exit");
scanf("%d",&c);
switch(c)
{
case 1:
fp=fopen("one.txt","r+");
display(fp);
fclose(fp);
break;
case 2:
fp=fopen("one.txt","r+");
printf("\nEnter ID to search : ");
scanf("%d",&id);
if(search(fp,id))
{
printf("\nThe record is as follows : ");
printf("\n%d\t%s",d.id,d.name);
}
else
printf("\nRecord not found");
fclose(fp);
break;
case 3:
fp=fopen("one.txt","r+");
printf("\nEnter ID to modify d record : ");
scanf("%d",&id);
if(search(fp,id))
{
printf("\nEnter new name");
scanf("%s",d.name);
fwrite(&d,sizeof(d),1,fp);
}
else
printf("\nSpecified record not found ");
fclose(fp);
break;
}
}
}
int search(FILE *fp,int id)
{
rewind(fp);
while(fread(&d,sizeof(d),1,fp))
{
if(id==d.id)
return 1;
}
return 0;
}
void display(FILE *fp)
{
rewind(fp);
while(fread(&d,sizeof(d),1,fp))
{
printf("\n%d\t%s",d.id,d.name);
}
}
答案 0 :(得分:2)
由于您使用的是固定大小的记录,因此很容易修改。只需搜索条目并在旧条目上写下新记录。请记住,在搜索完记录后,您必须向后搜索记录的开头。
至于删除记录,则更难。实际上,您必须将除要删除的记录之外的所有记录写入临时文件,然后将临时文件重命名为原始数据文件。或者在内存中完成所有操作,然后使用内存中的记录从头开始重写文件。
答案 1 :(得分:1)
感谢您提出这个问题。修改了代码以记住其文件位置,因为代码通过id扫描文件。请参阅curr_pos
字段以及ftell
和fseek
如何使用字段fflush
。另外,添加了一些#include<stdio.h>
#include<stdlib.h>
int c,i,id;
char name[20];
FILE *fp;
int n;
long curr_pos;
int search(FILE *fp,int id);
void display(FILE *fp);
typedef struct details
{
int id;
char name[20];
}details;
details d;
void main()
{
printf("\nHow many records you would like to insert ? : "); fflush(stdout);
scanf("%d",&n);
fp=fopen("one.txt","a");
for(i=0;i<n;i++)
{
printf("\nEnter id and name"); fflush(stdout);
scanf("%d%s",&d.id,d.name);
fwrite(&d,sizeof(d),1,fp);
}
fclose(fp);
while(1)
{
printf("\nWhat would you like to do now ? : \n");
printf("\n1.Display \t2.Search \t3.Modify \t4.Delete \t5.Exit\n");
fflush(stdout);
scanf("%d",&c);
switch(c)
{
case 1:
fp=fopen("one.txt","r+");
display(fp);
fclose(fp);
break;
case 2:
fp=fopen("one.txt","r+");
printf("\nEnter ID to search : "); fflush(stdout);
scanf("%d",&id);
if(search(fp,id))
{
printf("\nThe record is as follows : ");
printf("\n%d\t%s",d.id,d.name); fflush(stdout);
}
else
printf("\nRecord not found");
fclose(fp);
break;
case 3:
fp=fopen("one.txt","r+");
printf("\nEnter ID to modify d record : "); fflush(stdout);
scanf("%d",&id);
if(search(fp,id))
{
printf("\nEnter new name : "); fflush(stdout);
scanf("%s",d.name);
// back-up one record, to get to start of current record
fseek(fp, curr_pos, 0);
fwrite(&d,sizeof(d),1,fp);
}
else
printf("\nSpecified record not found ");
fclose(fp);
break;
}
}
}
int search(FILE *fp,int id)
{
rewind(fp);
curr_pos = ftell(fp);
while(fread(&d,sizeof(d),1,fp))
{
if(id==d.id) {return 1;}
curr_pos = ftell(fp);
}
return 0;
}
void display(FILE *fp)
{
rewind(fp);
while(fread(&d,sizeof(d),1,fp))
{
printf("\n%d\t%s",d.id,d.name);
}
}
语句以使其在Eclipse IDE上运行。
{{1}}
希望这有帮助。
答案 2 :(得分:0)
问题是您无法从文件中间删除数据。因此,您唯一能做的就是从头开始重写整个文件(直接或使用副本),或者您可以将记录标记为已删除。这将保留文件大小,当然。您可以不时地重写文件,删除所有已删除的记录,从而再次压缩文件。
这是一种可行的方法取决于你真正删除记录的频率,当然,如果删除了一条记录,你可以用一个新记录覆盖它,稍后当你插入一个记录时。