程序应根据员工ID修改或删除特定记录,在修改部分时,将修改后的记录作为新记录写入文件末尾,删除部分只能工作一次,然后给我一个分段错误。
修改:
如何修改代码以在同一位置重写已编辑的记录?
#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;
}
删除:
如何修改代码以使其多次删除记录?
#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;
}
答案 0 :(得分:1)
使用旨在用于处理文本文件fprintf的C函数来操作二进制文件并不好。
例如,在我的代码中,我看到:
fseek(fp,-sizeof(employee),SEEK_CUR);
fprintf(fp, "%d %s %d %d\n", employee.id, employee.name, employee.salary, employee.age);
这会给您带来问题,因为您在文件中作为二进制文件旅行,然后在其上写字符。你应该使用fwrite函数。
我的建议:检查整个程序,定义持久性策略并与此保持一致。
答案 1 :(得分:1)
我认为这是你的问题,首先你在sizeof
之前有一个减号,看到它有点奇怪,第二个SEEK_CUR
让你比当前文件更进一步看看fseek(), rewind()
fseek(fp,-sizeof(employee),SEEK_CUR); //This is not the definitive read below.
^------minus symbol. ^------- the type of seek.
我建议你做一些修改:
使用常见的Formatted File
让您的生活更轻松,请记住“完美就是简单”。
使用SEEK_SET
来使用文件开头的相对位置,然后使用struct's size
作为sizeof
的参数。
fseek( fp, sizeof( struct record_em), SEEK_SET );
使用member
ID作为接收器的密钥并使用一系列连续的数字,但显然您应该创建一个包含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:目前正在添加更多信息。
答案 2 :(得分:1)
SEEK_CUR
偏移量相对于当前文件指针位置。因此,实际上,您可以说,“移动到我当前位置加上30个字节”,或者“移动到我当前位置减去20个字节”。
例如。 fseek(fp, -30, SEEK_CUR)
REF。 http://beej.us/guide/bgc/output/html/multipage/fseek.html
我不认为他使用sizeof()
函数的否定是错误的。
但你最好还是使用sizeof(struct record_em)
来代替!
答案 3 :(得分:1)
以下是代码的关键点:
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);
}
以下是学生的结构:
struct student{
int roll;
char name[20];
}st;
这是修改/更新记录的一般方法。您可以为员工结构使用相同的语法。