1

I'm trying to delete a record from a file, by copying all of the records to a temporary file, except the one to be deleted. Then I delete the old file and rename the temporary file. Before renaming, I'm testing to see if the data actually transfers, but when I enter the prompted date and details, the program just freezes, even though the data I enter is from a record in the file. Can anyone help?

Here's the code:

void del_income() {
    Income I;
    Delete D;
    FILE *INCOME = fopen("C:\\income.txt", "a");
    FILE *TEMP = fopen("C:\\temporary.txt", "a");
    printf("Enter date of record to be deleted:");
    scanf("%s", D.date);
    printf("Enter job details of records to be deleted:");
    scanf("%s", D.details);
    while (1) {
        fscanf(INCOME, "%s %s %s %d %d %d %d %d",
               I.date, I.details, I.vehicleno, &I.rate, &I.hours, &I.subtotal,
               &I.vat, &I.total);
        if (feof(INCOME))
            break;
        if (strcmp(I.date, D.date) == 1 && strcmp(I.details, D.details) == 1)
            fprintf(TEMP, "%s %s %s %d %d %d %d %d",
                    I.date, I.details, I.vehicleno, I.rate, I.hours, I.subtotal,
                    I.vat, I.total);
    }
    fclose(INCOME);
    fclose(TEMP);
    system("cls");
}
3
  • 1
    Provide a minimal reproducible example, including definitions of Income and Delete, a complete program including all #include directives and a main function, contents of income.txt, and sample input. Commented Feb 10, 2020 at 0:37
  • 3
    Meanwhile: Do not rely on feof(INCOME). Instead, test the return value of fscanf. Do not rely on strcmp to return 1. The only guarantee from the C standard is that it return a value greater than 0 to indicate “greater than”. Commented Feb 10, 2020 at 0:39
  • Pay attention to the modes you use with fopen(). Commented Feb 10, 2020 at 0:42

1 Answer 1

2

There are multiple problems in your code:

  • INCOME should be open with mode "r", not "a"
  • TEMP should be open with mode "w", not "a"
  • return values from fopen and scanf should be tested to avoid undefined behavior on errors.
  • if (feof(INCOME)) is not the proper way to test for end of file, you should instead check if fscanf() succeeded at converting 8 values: it should return 8. Any other return value is either a format error, missing fields or the end of file.
  • strcmp(I.date, D.date) == 1 is incorrect: strcmp() returns 0 for identical strings, < 0 if I.date is lexicographically before D.date and > 0 if it compares greater. You should change your tests to:

    if (strcmp(I.date, D.date) != 0 || strcmp(I.details, D.details) != 0)
    
  • you should add a trailing newline in fprintf(TEMP, "%s %s %s %d %d %d %d %d", ...)

  • conversion formats for strings %s should specify the maximum number of characters to store to the destination arrays to avoid undefined behavior on invalid input. For example if D.date is an array of 50 bytes, you should write:

    if (scanf("%49s", D.date) != 1) { /* handle input error */ }
    
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.