Я не использую fseek () правильно? - PullRequest
0 голосов
/ 19 мая 2018

Я пытаюсь обновить некоторую информацию в моем двоичном файле, но я сталкиваюсь с проблемой при попытке вернуться назад к началу строки.

void updateSalary(char* filename)
{
    int i = 0;
    employee temp;
    char c;
    float increase;
    FILE *fup = fopen(filename, "rb+");
    if (fup == NULL)
    {
        printf("Unable to read the file\n");
        return;
    }

    fread(&temp, sizeof(employee), 1, fup);
    while (!feof(fup))
    {
    printf("How big is the increase to %s's salary?\n", temp.name);
    scanf("%f", &increase);
    temp.salary += increase;
    fseek(fup, (i * sizeof(employee)), SEEK_SET);
    fwrite(&temp, sizeof(employee), 1, fup);
    fread(&temp, sizeof(employee), 1, fup);
    i++;
    }
fclose(fup);
}

Проблема заключается в том, чтоНапример, если я выберу обновление 2 сотрудников, по какой-то причине цикл while не останавливается на 2-м сотруднике, и функция продолжает работать ..

Заранее спасибо.

Редактировать:кажется, что fwrite ();функция не продвигалась (по значению позиции) до следующей строки, поэтому есть фиксированный код:

void updateSalary(char* filename, float threshold)
{
    int i = 0;
    employee temp;
    char c;
    float increase;
    FILE *fup = fopen(filename, "r+b");
    if (fup == NULL)
    {
        printf("Unable to read the file\n");
        return;
    }
    //fread(&temp, sizeof(employee), 1, fup);
    while (fread(&temp, sizeof(employee), 1, fup))
    {
    printf("How big is the increase to %s's salary?\n", temp.name);
    rewind(stdin);
    scanf("%f", &increase);
    temp.salary += increase;
    fseek(fup, (i * sizeof(employee)), SEEK_SET);
    fwrite(&temp, sizeof(employee), 1, fup);
    **fseek(fup, ((i+1) * sizeof(employee)), SEEK_SET);**
    i++;
    }
fclose(fup);
}

1 Ответ

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

Вы должны проверить мелкий шрифт в документации fopen:

В режиме обновления ('+') могут выполняться как ввод, так и вывод, но выводне может сопровождаться вводом без промежуточного вызова fflush, fseek, fsetpos или rewind, а за вводом не может следовать вывод без промежуточного вызова fseek, fsetpos или rewind, если только операция ввода не встретила конец файла.

Чтение и запись могут быть буферизованы, но все же использовать одну позицию файла.Переключение режимов без предупреждения о времени выполнения (с использованием fseek) может привести к сбоям в буферизации.

Таким образом, строки

fseek(fup, (i * sizeof(employee)), SEEK_SET);
fwrite(&temp, sizeof(employee), 1, fup);
fread(&temp, sizeof(employee), 1, fup);

нуждаются еще в одном fseek между записью и чтением.

...