我试图通过用'标记它来从二进制文件中删除一个Employee。 *'在Employee.Firstname的第一个字节,但是如果该文件上有多个员工,我尝试删除第二个员工,并将其标记为删除' *'它只会标记第一个Employee.Firstname的第一个字节,其中包含' *'。
以下是我写文件的方式:
struct EmployeeInformation{
char Firstname[32];
char Lastname[32];
char Address[32];
char ID[8];
char Duration[8];
}
struct EmployeeInformation Employee;
void AddEmployee()
{
FILE *fd;
printf("\n\n>>Add Employee<<\n");
//I use fgets and get all Employee info I just didn't include it for reading purposes.
if((fd = fopen(BINARY_FILE, "ab+")) == NULL)
{
printf("Error in opening file.\n\n");
getchar();
}
else
{
//Write Employee to file.
fwrite(&Employee, sizeof(Employee), 1, fd);
printf("\nEmployee Added!\n\n");
}
fclose(fd);
}
以下是删除员工的代码。
void DeleteEmployee()
{
FILE *fd;
char EmployeeID[8];
long Pos = 0;
fpos_t pos;
printf("\n>>Delete Employee<<\n");
//Ask user for ID of employee they wish to delete.
printf("Employee ID:");
fgets(EmployeeID, 6, stdin);
if ((fd = fopen(BINARY_FILE, "rb+")) == NULL)
{
printf("Error, Cannot Open File.\n");
}
else
{
while(fread(&Employee, sizeof(struct EmployeeInformation), 1, fd) != 0)
{
if(strcmp(EmployeeID, Employee.ID) == 0)
{
//Employee Found
printf("Employee Found!\n");
//Get Current Position in file.
Pos = fgetpos(fd, &pos);
//Go to that Postion.
fseek(fd, Pos, SEEK_SET);
//Mark for deletion with '*'
fputc('*', fd);
printf("Firstname: %s\n",Employee.Firstname);
}
else
{
printf("Employe Not Found!\n\n");
}
}
}
fclose(fd);
}
答案 0 :(得分:2)
您刚从fgetpos
获得的位置>> 您刚刚阅读的记录。您需要在执行阅读前致电fgetpos
或在致电sizeof(struct EmployeeInformation)
之前从该职位中减去fseek
。当你向后搜索然后写一个字节时,你也会弄乱当前的位置。最后,fgetpos
并没有回复你的想法;将其替换为ftell
。
我会建议:
long int pos = ftell(fd);
while(fread(&Employee, sizeof(struct EmployeeInformation), 1, fd) != 0)
{
if(strcmp(EmployeeID, Employee.ID) == 0)
{
//Employee Found
printf("Employee Found!\n");
//Go to the BEGINNING of the record
fseek(fd, pos, SEEK_SET);
//Mark for deletion with '*'
fputc('*', fd);
printf("Firstname: %s\n",Employee.Firstname);
//Now position back to the end of the record (-1 because we advanced 1
//byte when we did fputc() above
fseek(pd, pos+sizeof(struct EmployeeInformation)-1, SEEK_SET);
}
else
{
printf("Employe Not Found!\n\n");
}
//We should now be at the beginning of the next record - mark the position
pos = ftell(fd);
}
答案 1 :(得分:0)
而不是:
fseek(fd, Pos, SEEK_SET);
DO
fsetpos(f, &pos);
......或类似的东西,很可能你必须减去sizeof(Employee)
。
确保您寻找正确的位置,来自正确的变量,并包含正确的值。
如果您的文件不是太长,请使用ftell
和fseek
进行定位。否则,请使用fgetpos
和fsetpos
。永远不要混合这些。
答案 2 :(得分:0)
既然你正在阅读每个单独的记录,直到找到你要找的那个记录,你可以有一个计数器来计算读取的记录数,然后当你找到你要删除的记录时就行了
fseek( fp, (current-1)*sizeof(Employee), SEEK_SET);
fputc( '*', fp );
然后
fseek(fp, current*sizeof(Employee), SEEK_SET);
定位于下一个结构,因为写'*'将移动fp。