Разрешено ли использовать freopen с режимом "w +" для стандартного ввода? - PullRequest
3 голосов
/ 09 февраля 2020

Рассмотрим следующий код:

freopen("buffer.txt", "w+", stdin);
fprintf(stdin, "hello");
fseek(stdin, 0, SEEK_SET);
char str[16];
scanf("%s", str);
printf("%s", str);

В стандарте я не нашел ни одной записи, запрещающей мне это делать, но также нет записей, явно разрешающих это. Стоит ли ожидать, что этот код будет работать на любом стандартном совместимом компиляторе? Будет ли какая-либо стандартная функция ввода / вывода прервана или приведет к UB, если stdin (или stdout) будет открыт в режиме чтения-записи? А как насчет потоков C ++?

1 Ответ

3 голосов
/ 09 февраля 2020

С C ++ стандарт для freopen Функция:

FILE * freopen (const char * имя файла, режим const char *, FILE * поток );

mode

C строка, содержащая режим доступа к файлу. Это может быть:

...

w + - запись / обновление: создайте пустой файл и откройте его для обновления (как для ввода, так и для вывода). Если файл с таким именем уже существует, его содержимое отбрасывается, и файл обрабатывается как новый пустой файл.

Таким образом, по стандарту это совершенно законно.

Однако, если вы хотите быть более уверенным, проверьте, является ли возвращаемое значение нулевым указателем или нет. Или даже больше, проверьте переменную errno, если для нее задан системный код ошибки c при сбое.

Более того, если вы присмотритесь к документам freopen, вы увидите см. следующее предложение:

Эта функция особенно полезна для перенаправления предопределенных потоков, таких как stdin , stdout и stderr, для указания c файлов.

Это еще одно подтверждение того, что w+ разрешено использовать stdin.

...