在这段代码中,我想从文件中删除用户的特定记录,但我不能这样做。我使用这种方法来覆盖文件。首先,我做了一个临时文件,我写的所有其他记录,除了一个我必须删除。现在我删除了原始文件,并将临时文件重命名为原始文件。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct taxpayer
{
char name[50];
int Pancard_Number;
int Mobileno;
float income;
float tax;
};
void add_record(FILE *file)
{
struct taxpayer record;
printf("Enter name: ");
scanf("%s", record.name);
printf("Enter 5-digit Pancard_number: ");
scanf("%d", &record.Pancard_Number);
printf("Enter Mobileno: ");
scanf("%d", &record.Mobileno);
printf("Enter income: ");
scanf("%f", &record.income);
if (record.income <= 25000)
{
record.tax = 0;
}
else if (record.income > 25000 && record.income <= 50000)
{
record.tax = (record.income - 25000) * 0.05;
}
else if (record.income > 50000 && record.income <= 75000)
{
record.tax = 1250 + ((record.income - 50000) * 0.2);
}
else if (record.income > 75000 && record.income <= 100000)
{
record.tax = 5520 + ((record.income - 75000) * 0.3);
}
else
{
record.tax = 11250 + ((record.income - 100000) * 0.4);
}
// record.tax = record.income * 0.1; // 10% tax rate
fwrite(&record, sizeof(struct taxpayer), 1, file);
printf("Record added successfully.\n");
}
void show_allrecord(FILE *file)
{
// rewind(file);
struct taxpayer record;
fseek(file, 0, SEEK_SET);
printf("%-20s %-20s %-20s %-20s \n", "Name", "PancardNo.", "Income", "TaxPaid");
while (fread(&record, sizeof(struct taxpayer), 1, file))
{
printf("%-20s %-19d Rs.%-19.2f Rs.%-17.2f \n", record.name, record.Pancard_Number, record.income, record.tax);
}
}
void search_record(FILE *file)
{
// char name[50];
int search;
struct taxpayer record;
printf("Enter pancard number to search: ");
scanf("%d", &search);
fseek(file, 0, SEEK_SET);
while (fread(&record, sizeof(struct taxpayer), 1, file))
{
if (record.Pancard_Number == search)
{
printf("%-20s %-20s %-20s %-20s \n", "Name", "PancardNo.", "Income", "TaxPaid");
printf("%-20s %-19d Rs.%-19.2f Rs.%-17.2f \n", record.name, record.Pancard_Number, record.income, record.tax);
return;
}
}
printf("Record not found.\n");
}
void edit_record(FILE *file)
{
char name[50];
struct taxpayer record;
printf("Enter name to edit: ");
scanf("%s", name);
fseek(file, 0, SEEK_SET);
while (fread(&record, sizeof(struct taxpayer), 1, file))
{
if (strcmp(record.name, name) == 0)
{
printf("Enter new income: ");
scanf("%f", &record.income);
if (record.income <= 25000)
{
record.tax = 0;
}
else if (record.income > 25000 && record.income <= 50000)
{
record.tax = (record.income - 25000) * 0.05;
}
else if (record.income > 50000 && record.income <= 75000)
{
record.tax = 1250 + ((record.income - 50000) * 0.2);
}
else if (record.income > 75000 && record.income <= 100000)
{
record.tax = 5520 + ((record.income - 75000) * 0.3);
}
else
{
record.tax = 11250 + ((record.income - 100000) * 0.4);
}
// record.tax = record.income * 0.1;
fseek(file, -sizeof(struct taxpayer), SEEK_CUR);
fwrite(&record, sizeof(struct taxpayer), 1, file);
printf("Record updated successfully.\n");
return;
}
}
printf("Record not found.\n");
}
void delete_record(FILE *file) {
char name[30];
printf("Enter the name of the taxpayer to delete: ");
scanf("%s", name);
fseek(file, 0, SEEK_SET);
struct taxpayer record;
int found = 0;
// Create a temporary file
FILE *temp = fopen("temp.txt", "wb");
// Read each record from the file and write to the temporary file except for the one to be deleted
while (fread(&record, sizeof(record), 1, file) == 1) {
if (strcmp(record.name, name) == 0) {
found = 1;
}
else {
fwrite(&record, sizeof(record), 1, temp);
}
}
fclose(file);
fclose(temp);
if (found) {
// Delete the original file and rename the temporary file to the original file name
remove("taxpayers.txt");
rename("temp.txt", "taxpayers.txt");
printf("Taxpayer with name %s has been deleted.\n", name);
} else {
printf("Taxpayer with name %s not found.\n", name);
remove("temp.txt");
}
// Open the original file for appending
file = fopen("taxpayers.txt", "ab");
if (file == NULL) {
printf("Error opening file.\n");
exit(1);
}
}
int main()
{
FILE *file = fopen("taxpayers.txt", "ab+");
if (file == NULL)
{
printf("Error opening file.\n");
exit(1);
}
int choice;
do
{
printf("\n1. Add New Record\n");
printf("2. List All Tax Payer along with Income Tax to be paid\n");
printf("3. Search\n");
printf("4. Edit\n");
printf("5. Delete Record\n");
printf("6. Exit\n");
printf("Enter your choice: ");
fflush(stdin);
scanf("%d", &choice);
switch (choice)
{
case 1:
add_record(file);
break;
case 2:
show_allrecord(file);
break;
case 3:
search_record(file);
break;
case 4:
edit_record(file);
break;
case 5:
delete_record(file);
break;
case 6:
printf("Exiting...\n");
break;
default:
printf("Invalid choice. Please try again.\n");
break;
}
} while (choice != 6);
fclose(file);
return 0;
}
我能够正确运行所有函数,但一旦我运行delete_record函数,我就无法执行其他函数。
请更正此代码,以便我能够从文件中删除一个特定的记录,也能够执行其他功能也
1条答案
按热度按时间ql3eal8s1#
delete_record()
:当您在中重新打开文件时,您使用了不正确的模式“ab”,但应该是“ab+”,因为您打算从中读取。这是一个信号,你应该避免重复自己。delete_record()
:file = fopen("taxpayers.txt", "ab+");
将更新变量file
的副本,但它在函数之外没有任何影响。返回新的FILE *
或将参数作为FILE **file
传入。你也可以,至少在Linux上,删除fclose(file);
并将后面的`fopen()改为:这将是实现你想要的最小的改变。
1.(留给读者练习)阅读字符串时,始终指定最大字段宽度
scanf()
。1.你不验证你的输入。例如,如果您有两个同名的人,则他们都将被删除。5位数的pan编号不会检查您是否输入了4或6位数。
1.您应该检查
scanf()
是否读取了预期的元素数。如果你给予它一个无效的菜单输入,比如‘q’,它会触发一个无限循环。优雅寻址的方法是在错误时刷新输入缓冲区:示例会话: