c++ - 在 freopen(..,"r",stdin) + fclose(stdin) 之后,进一步的 std::cin 不起作用
问题描述
int main(){
int a,b;
std::cin >> a >> b; // first
freopen("test.txt","r",stdin);
std::cin >> a >> b; // second
fclose(stdin);
cout << a << ", " << b << endl;
freopen("test2.txt","r",stdin);
std::cin >> a >> b; // third
fclose(stdin);
cout << a << ", " << b << endl;
std::cin >> a >> b; // fourth
return 0;
}
此代码块将混合来自终端和文件的输入。第一个、第二个和第三个 cin 工作正常,但第四个失败了。似乎 fclose(stdin) 在这里没有功能。
解决方案
对象 cin 控制来自与对象 stdin 关联的流缓冲区的输入,该对象在 <cstdio> 中声明。
读取std::cin
与读取相同stdin
。这意味着fclose(stdin)
使用后std::cin
就像调用scanf("%d", &a)
.
这正是在第三种情况下发生的情况, where fclose(stdin)
is called before reading std::cin
。相比之下,代码读取的案例 1-3std::cin
之前fclose(stdin)
.
从封闭stdin
的读取可能是未定义的。以下是c11 草案对此的看法:
7.21.7.1 fgetc 函数
...
int fgetc(FILE *stream);
...
返回: 如果设置了流的文件结束指示符,或者如果流处于文件结束位置,则设置流的文件结束指示符并且 fgetc 函数返回 EOF。否则,fgetc 函数从 stream 指向的输入流中返回下一个字符。如果发生读取错误,则设置流的错误指示符并且 fgetc 函数返回 EOF。
本文涵盖了从打开的 stdin 读取的所有情况(成功、文件结束和读取错误),但它们不涉及流因fclose
. 我在涵盖此案例的标准中找不到任何内容,这意味着该案例未定义。
结论std::cin
:从after读取fclose(stdin)
,没有任何进一步freopen
是未定义的行为。尝试读取已关闭的 C 流可能会引用已释放的资源。
推荐阅读
- java - 我想将矩形刻入网格。如何获取与矩形碰撞的网格单元的列表
- tensorflow - 批量大小> 1的自定义TensorFlow损失函数?
- codeception - 如何在 Codeception FactoryMuffin 中使用数据库中的现有数据?
- python - 使用 Python 将带有 xsd 的 xml 解析为 CSV?
- c# - 绑定到 getter 属性时,Xamarin IsVisible 不会动态更新
- r - 在 R 中使用 gls 函数时出现奇点错误
- apache-kafka - 使用 Snowflake 和 Kafka 连接器的日志和语句
- java - 我可以在 Map 中有两个同名的键吗?
- azure-cognitive-search - azure search S3 HD 定价层的文档计数限制
- python - 如何将多个nc文件中的特定参数导入python中的xarray