在此收入管理中,我的delete_record函数不起作用

v1l68za4  于 2023-04-29  发布在  其他
关注(0)|答案(1)|浏览(105)

在这段代码中,我想从文件中删除用户的特定记录,但我不能这样做。我使用这种方法来覆盖文件。首先,我做了一个临时文件,我写的所有其他记录,除了一个我必须删除。现在我删除了原始文件,并将临时文件重命名为原始文件。

#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函数,我就无法执行其他函数。
请更正此代码,以便我能够从文件中删除一个特定的记录,也能够执行其他功能也

ql3eal8s

ql3eal8s1#

  1. delete_record():当您在中重新打开文件时,您使用了不正确的模式“ab”,但应该是“ab+”,因为您打算从中读取。这是一个信号,你应该避免重复自己。
  2. delete_record()file = fopen("taxpayers.txt", "ab+");将更新变量file的副本,但它在函数之外没有任何影响。返回新的FILE *或将参数作为FILE **file传入。你也可以,至少在Linux上,删除fclose(file);并将后面的`fopen()改为:
file = freopen("taxpayers.txt", "ab+", file)

这将是实现你想要的最小的改变。
1.(留给读者练习)阅读字符串时,始终指定最大字段宽度scanf()
1.你不验证你的输入。例如,如果您有两个同名的人,则他们都将被删除。5位数的pan编号不会检查您是否输入了4或6位数。
1.您应该检查scanf()是否读取了预期的元素数。如果你给予它一个无效的菜单输入,比如‘q’,它会触发一个无限循环。优雅寻址的方法是在错误时刷新输入缓冲区:

int flush() {
   for(;;) {
      int ch = getchar();
      if(ch == EOF || ch == '\n') return ch;
   }
}

// ...

        if(scanf("%d", &choice) != 1) {
              if(flush() == EOF) exit(0);
              continue;
        }
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(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 = freopen("taxpayers.txt", "ab+", file);
    if (file == NULL) {
        printf("Error opening file.\n");
        exit(1);
    }
}

示例会话:

1. Add New Record
2. List All Tax Payer along with Income Tax to be paid
3. Search
4. Edit
5. Delete Record
6. Exit
Enter your choice: 2
Name                 PancardNo.           Income               TaxPaid               
jane                 23456               Rs.4.00                Rs.0.00               

1. Add New Record
2. List All Tax Payer along with Income Tax to be paid
3. Search
4. Edit
5. Delete Record
6. Exit
Enter your choice: 1
Enter name: bob
Enter 5-digit Pancard_number: 23456
Enter Mobileno: 2
Enter income: 2
Record added successfully.

1. Add New Record
2. List All Tax Payer along with Income Tax to be paid
3. Search
4. Edit
5. Delete Record
6. Exit
Enter your choice: 5
Enter the name of the taxpayer to delete: jane 
Taxpayer with name jane has been deleted.

1. Add New Record
2. List All Tax Payer along with Income Tax to be paid
3. Search
4. Edit
5. Delete Record
6. Exit
Enter your choice: 2
Name                 PancardNo.           Income               TaxPaid               
bob                  23456               Rs.2.00                Rs.0.00

相关问题