переименование и удаление файла не работает только на первой итерации (C) - PullRequest
0 голосов
/ 20 мая 2018

Я создал программу, которая создает бинарный файл, вставляет данные сотрудников (код, имя, зарплата).Затем программа увеличивает заработную плату каждого сотрудника путем ввода данных пользователем и проверяет, превышает ли зарплата пороговое значение.Если это так, сотрудник будет удален из файла.

Все работает почти идеально, но есть одна проблема. Я нашел решение для двух случаев:

Если впоместите, создайте один, затем обновите его - 100% работает.

В противном случае (если файл уже существует), спросите пользователя, не хочет ли он отредактировать его.(если он выберет «нет», то программа создаст и новый файл).Любой из параметров, по какой-то причине, попав в часть обновления, не работает, и никаких изменений не было сделано ... программа печатает старый файл. но , если я закрою окно и снова запущу программу, во второй раз, , она будет работать .

Я мог видеть, что файл temp.dat, который создает программа, все еще существует на первой итерации.

Есть предложения?

main:

void Ex1()
{
    char filename[13] = "employee.dat";
    char c=NULL;
    float threshold = 5000;
    FILE *fin = fopen(filename, "rb");

    if (fin == NULL)
    {
        printf("Creating a new file.. \n");
        fin = fopen(filename, "wb"); //creating a new blank file
        fclose(fin);
        get_Employee(filename);
        printf("Okay, this is what we have:\n");
        print_Bin_File(filename);
        printf("Now, let's increase the salary!\n");
        updateSalary(filename, threshold);
        printf("The updated file:\n");
        print_Bin_File(filename);
    }
    else
    {
        while (c != 'Y' || c != 'y' || c != 'N' || c != 'n')
        {
            printf("There is already an existing file:\n");
            print_Bin_File(filename);
            printf("Do you wish to update the current file? (Y/N)\n");
            rewind(stdin);
            c = getchar();
            rewind(stdin);
            if (c == 'Y' || c == 'y')
            {
                fclose(fin);
                printf("Ok, let's increase the salary!\n");
                updateSalary(filename, threshold);
                print_Bin_File(filename);
                return;
            }
            else
            {
                if (c == 'N' || c == 'n')
                {
                    printf("Creating a new file.. \n");
                    fin = fopen(filename, "wb"); //creating a new blank file
                    fclose(fin);
                    get_Employee(filename);
                    printf("Okay, this is what we have:\n");
                    print_Bin_File(filename);
                    printf("Now, let's increase the salary!\n");
                    updateSalary(filename, threshold);
                    print_Bin_File(filename);
                    return;
                }
                else
                    printf("invalid input\n");

            }
        }
    }

}

функция обновления:

void updateSalary(char* filename, float threshold)
{
    employee temp;
    char c;
    float increase;
    FILE *fup = fopen(filename, "rb+");
    FILE *ftmp = fopen("temp.dat", "wb+");
    if (fup == NULL)
    {
        printf("Unable to read the file\n");
        return;
    }
    while (fread(&temp, sizeof(employee), 1, fup)) //fread will return 0 when reaching EOF - safer then using (!feof)
    {
        printf("How big is the increase to %s's salary?\n", temp.name);
        scanf("%f", &increase);
        temp.salary += increase;

        if (temp.salary<threshold)
        {
            fwrite(&temp, sizeof(employee), 1, ftmp);
        }
    }
    fclose(ftmp);
    fclose(fup);

remove(filename);
rename("temp.dat", filename);`enter code here`
}

EDIT: Исправление былодобавить fclose(fin); до fin = fopen(filename, "wb");.

1 Ответ

0 голосов
/ 20 мая 2018

При написании кода я предполагал, что если будет предпринята неудачная попытка прочитать файл (if (fin == NULL)), то указатель файла (fin) также будет "закрыт""(как fclose (); делает), и я мог бы легко написать новый файл.

Я недостаточно читал о fopen ();и fclose ();функций, но, похоже, , если вы хотите проверить, была ли успешная попытка, , чтобы прочитать файл, а затем написать один, вы должны использовать fclose ();до того, как вы прочли файл, либо он был успешным, либо неуспешным.

обновленный файл main:

void Ex1()
{
    char filename[13] = "employee.dat";
    char c=NULL;
    float threshold = 5000;
    FILE *fin = fopen(filename, "rb");

    if (fin == NULL)
    {
        printf("Creating a new file.. \n");
        fclose(fin);
        fin = fopen(filename, "wb"); //creating a new blank file
        fclose(fin);
        get_Employee(filename);
        printf("Okay, this is what we have:\n");
        print_Bin_File(filename);
        printf("Now, let's increase the salary!\n");
        updateSalary(filename, threshold);
        printf("The updated file:\n");
        print_Bin_File(filename);
    }
    else
    {
        while (c != 'Y' || c != 'y' || c != 'N' || c != 'n')
        {
            printf("There is already an existing file:\n");
            print_Bin_File(filename);
            printf("Do you wish to update the current file? (Y/N)\n");
            rewind(stdin);
            c = getchar();
            rewind(stdin);
            if (c == 'Y' || c == 'y')
            {
                fclose(fin);
                printf("Ok, let's increase the salary!\n");
                updateSalary(filename, threshold);
                print_Bin_File(filename);
                return;
            }
            else
            {
                if (c == 'N' || c == 'n')
                {
                    printf("Creating a new file.. \n");
                    fclose(fin);
                    fin = fopen(filename, "wb"); //creating a new blank file
                    fclose(fin);
                    get_Employee(filename);
                    printf("Okay, this is what we have:\n");
                    print_Bin_File(filename);
                    printf("Now, let's increase the salary!\n");
                    updateSalary(filename, threshold);
                    print_Bin_File(filename);
                    return;
                }
                else
                    printf("invalid input\n");

            }
        }
    }

}
...