Зачем мне очищать поток ввода-вывода, чтобы получить правильный результат? - PullRequest
10 голосов
/ 09 февраля 2010

Почему приведенный ниже код не работает? Я имею в виду, он показывает все виды странных символов на консоли вывода.

#include <stdio.h>
char mybuffer[80];
int main()
{
    FILE * pFile;
    pFile = fopen ("example.txt","r+");
    if (pFile == NULL) perror ("Error opening file");

    else {
        fputs ("test",pFile);

        fgets (mybuffer,80,pFile);
        puts (mybuffer);
        fclose (pFile);
        return 0;
    }
}

Однако приведенный ниже код работает хорошо.

#include <stdio.h>
char mybuffer[80];
int main()
{
    FILE * pFile;
    pFile = fopen ("example.txt","r+");
    if (pFile == NULL) perror ("Error opening file");

    else {
        fputs ("test",pFile);
        fflush (pFile);    
        fgets (mybuffer,80,pFile);
        puts (mybuffer);
        fclose (pFile);
        return 0;
    }
}

Почему мне нужно очистить поток, чтобы получить правильный результат?

Ответы [ 3 ]

12 голосов
/ 09 февраля 2010

Поскольку в стандарте говорится так (§7.19.5.3 / 5):

Когда файл открывается в режиме обновления («+» как второй или третий символ в приведенном выше списке аргументов режима значения), оба входа и выхода могут быть выполняется на связанном потоке. Однако вывод не должен быть напрямую с последующим вводом без промежуточный звонок на флеш функция или позиционирование в файл функция (fseek, fsetpos или rewind), и вход не должен быть напрямую с последующим выводом без промежуточный вызов позиционирования файла функция, если только операция ввода встречает конец файла.

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

7 голосов
/ 09 февраля 2010

При использовании файла с режимом чтения / записи вы должны вызывать fseek / fflush перед различными операциями ввода / вывода.

См. Этот ответ на , почему всегда требуются fseek или fflush ...

2 голосов
/ 09 февраля 2010

, потому что файл C io работает с использованием буфера. Это записывается только на диск, когда вы его очищаете, пишете символ / n или заполняете буфер.

Итак, в первом случае ваш файл ничего не содержит, когда вы приходите к нему читать.

...