Зачем мне нужно очищать поток ввода-вывода, чтобы получить правильный результат?

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

#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;
    }
}

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

Ответ 1

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

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

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

Ответ 2

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

Посмотрите этот ответ на почему fseek или fflush всегда требуется...

Ответ 3

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

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