C语言 从 C 中的随机访问文件中编辑/修改和删除记录
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13540193/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Edit/Modify & Delete of record from a Random Access File in C
提问by fatimah
The program should modify or delete a specific record according to employee id, in modifying part it writes the modified record as a new one at the end of the file, the deleting part works only once and then give me a segmentation fault.
程序应该根据员工ID修改或删除特定记录,在修改部分它将修改后的记录作为新记录写入文件末尾,删除部分只工作一次,然后给我一个分段错误。
Modifying:
修改:
How can I modify the code to rewrite the edited record in the same position?
如何修改代码以在同一位置重写已编辑的记录?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdlib.h>
struct record_em{
int id;
char name[20];
int salary;
int age;
};
int main( void )
{
struct record_em employee;
FILE *fp;
int n;
int ch;
fp = fopen("empRecord.dat","rb+");
printf("Enter Id Number:\n");
scanf("%d",&n);
rewind(fp);
while (!feof(fp)){
fscanf(fp,"%d %s %d %d", &employee.id, employee.name, &employee.salary, &employee.age);
if (employee.id==n){
printf("%d %s %d %d \n",employee.id, employee.name, employee.salary,employee.age);
printf("\n Do you want to change the name ?\n");
scanf("%d",&ch);
if (ch==1){
printf("Enter new name:\n");
scanf("%s",employee.name);
}
printf("\n Do you want to change the salary ?(y/n)\n");
scanf("%d",&ch);
if ( ch==2 ){
printf("Enter new salary:\n");
scanf("%d",&employee.salary);
}
printf("\n Do you want to change the age ?(y/n)\n");
scanf("%d",&ch);
if ( ch==3 ){
printf("Enter new age:\n");
scanf("%d",&employee.age);
}
fseek(fp,-sizeof(employee),SEEK_CUR);
fprintf(fp, "%d %s %d %d\n", employee.id, employee.name, employee.salary, employee.age);
exit(0);
}
}
printf("Record Not Found \n");
return 0;
}
Deleting:
删除:
How can I modify the code to make it delete records as many times as I want?
如何修改代码以使其根据需要多次删除记录?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdlib.h>
struct record_em{
int id;
char name[20];
int salary;
int age;
};
int main()
{
struct record_em employee;
FILE *fp, *ft;
int n;
fp = fopen("empRecord.dat","r");
ft = fopen("Temp.dat","wb+");
printf("\nEnter ID of employee to delete ");
scanf("%d",&n);
rewind(fp);
while (!feof(fp)){
fscanf(fp,"%d %s %d %d", &employee.id, employee.name, &employee.salary, &employee.age);
if(employee.id!=n){
fprintf(ft, "%d %s %d %d\n", employee.id, employee.name, employee.salary, employee.age);
}
}
fclose(fp);
fclose(ft);
remove("empRecord.dat");
rename("Temp.dat","EempRecord.dat");
return 0;
}
回答by Sachin Kumar
Here is the Key point of code:
这是代码的关键点:
void update(char filename[],char name[])
{
int records=0;
FILE *fp = fopen(filename,"rb+");
while(fread(&st,sizeof(st),1,fp)==1)
{
if(strcmp(name,st.name)==0)
{
printf("\nEnter new name: ");
scanf("%s",st.name);
printf("\nEnter new roll no.: ");
scanf("%d",&st.roll);
fseek(fp,sizeof(struct student)*records,SEEK_SET);//This is key line..
fwrite(&st,sizeof(st),1,fp);
}
records++; // in the while loop...
}
fclose(fp);
}
Below is the structure of student:
下面是学生的结构:
struct student{
int roll;
char name[20];
}st;
This is the general method to modify/update the record. You can use same syntax for your employee structure.
这是修改/更新记录的通用方法。您可以对员工结构使用相同的语法。
回答by Hernan Velasquez
It's not good to manipulate a binary file using the C functions that are intended to be used to manipulate text files fprintf.
使用旨在用于操作文本文件 fprintf 的 C 函数来操作二进制文件是不好的。
For example, in your code I see:
例如,在您的代码中,我看到:
fseek(fp,-sizeof(employee),SEEK_CUR);
fprintf(fp, "%d %s %d %d\n", employee.id, employee.name, employee.salary, employee.age);
This will bring you problems, since you are traveling within your file as a binary file to then write characters on it. You shoud use the fwrite function instead.
这会给您带来问题,因为您将文件作为二进制文件在文件中移动,然后在其上写入字符。您应该改用 fwrite 函数。
My recommendation: check your whole program, define your persistence strategy and be consistent with this.
我的建议:检查你的整个程序,定义你的持久性策略并与此保持一致。
回答by Alberto Bonsanto
I think here is your problem, first you have a minus sign before the sizeofit's a bit weird to see that, and second the SEEK_CURmakes you move further than your current file is so take a look here fseek(), rewind()
我认为这是你的问题,首先你有一个减号sizeof,看到它有点奇怪,其次SEEK_CUR让你比当前文件移动得更远,所以看看这里fseek(), rewind()
fseek(fp,-sizeof(employee),SEEK_CUR); //This is not the definitive read below.
^------minus symbol. ^------- the type of seek.
I recommend You to do some modifications:
我建议你做一些修改:
Use a common
Formatted Fileto make your life easier, remember "The perfection is the simplicity".Use
SEEK_SETto use the relative position from the beginning of the file, second use thestruct's sizeas the parameter forsizeof.fseek( fp, sizeof( struct record_em), SEEK_SET );Use the
memberid as the key of your sink and use a consecutive series of numbers, but obviously you should have created a file with 100, 1000 employers.1 Andrew 20000 27 ^ ^ ^ ^_____ age | | |__________ salary ( I would have used double here) | |_________________ name |_____________________ id ( Key for the relative position from the beginning)You will have to change your mind, and when you imagine "delete" a record you will write a white space (with exception of the key) example Imagine that the poor Andrew was fired and you will delete his record.
1 "Empty space" 0 0 ^ ^ ^ ^______ age (0 = nothing) | | |__________ salary (0 = nothing) | |____________________ name ("" = nothing) |____________________________ id ( Key for the relative position from the beginning)
用一个共同
Formatted File让你的生活更轻松,记住“完美就是简单”。使用
SEEK_SET使用的相对位置从文件的开头,第二次使用struct's size作为参数sizeof。fseek( fp, sizeof( struct record_em), SEEK_SET );使用
memberid 作为您的接收器的键并使用一系列连续的数字,但显然您应该创建一个包含 100、1000 个雇主的文件。1 Andrew 20000 27 ^ ^ ^ ^_____ age | | |__________ salary ( I would have used double here) | |_________________ name |_____________________ id ( Key for the relative position from the beginning)你将不得不改变主意,当你想象“删除”一个记录时,你会写一个空白(除了键)示例想象一下可怜的安德鲁被解雇了,你将删除他的记录。
1 "Empty space" 0 0 ^ ^ ^ ^______ age (0 = nothing) | | |__________ salary (0 = nothing) | |____________________ name ("" = nothing) |____________________________ id ( Key for the relative position from the beginning)
PD:currently adding more information.
PD:目前正在添加更多信息。
回答by Swaathi Kakarla
SEEK_CUR
offset is relative to the current file pointer position. So, in effect, you can say, "Move to my current position plus 30 bytes," or, "move to my current position minus 20 bytes."
eg. fseek(fp, -30, SEEK_CUR)ref. http://beej.us/guide/bgc/output/html/multipage/fseek.html
offset 是相对于当前文件指针位置的。因此,实际上,您可以说“移至我当前的位置加 30 个字节”,或“移至我的当前位置减 20 个字节”。例如。fseek(fp, -30, SEEK_CUR)参考 http://beej.us/guide/bgc/output/html/multipage/fseek.html
I don't think he is wrong in using the negative of the sizeof()function.
But you would be better off using the sizeof(struct record_em)instead!
我不认为他使用sizeof()函数的负数是错误的。但是你最好使用sizeof(struct record_em)代替!

