是否允许将 freopen 与 "w+" 模式一起用于标准输入?

Is it allowed to use freopen with "w+" mode for stdin?

考虑以下代码:

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

我发现标准中没有任何条目限制我这样做,但也没有条目明确允许这样做。我是否应该期望此代码适用于任何符合标准的编译器?如果以读写模式打开 stdin(或 stdout),任何标准 i/o 函数是否会中断或导致 UB? C++ 流怎么样?

来自 C++ standard 用于 freopen 函数:

FILE * freopen ( const char * filename, const char * mode, FILE * stream );

mode

C string containing a file access mode. It can be:

...

w+ - write/update: Create an empty file and open it for update (both for input and output). If a file with the same name already exists its contents are discarded and the file is treated as a new empty file.

因此,按照标准,这是完全合法的。

但是,如果您想更加确定,请检查 return 值是否为空指针。或者甚至更多,检查 errno 变量是否设置为失败时系统特定的错误代码。

此外,如果您仔细查看 freopen 文档,您会看到以下句子:

This function is especially useful for redirecting predefined streams like stdin, stdout and stderr to specific files.

这是对 stdin 合法使用 w+ 的又一次确认。