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控制与在<cstdio>中声明的对象stdin相关联的流缓冲区的输入。
从std::cin
读取与从stdin
读取相同。这意味着使用fclose(stdin)
的std::cin
就像调用scanf("%d", &a)
。
这正是在第三种情况下发生的情况,其中fclose(stdin)
在读取std::cin
之前被调用。相反,案例1-3代码在std::cin
之前读取fclose(stdin)
。
从封闭的stdin
读取可能是不确定的。以下是c11 draft对此的评价:
7.21.7.1 fgetc函数
...
int fgetc(FILE *stream);
...
返回:如果设置了流的文件结束指示符,或者流位于文件结尾,则设置流的文件结束指示符,并且fgetc函数返回EOF。否则,fgetc函数返回stream指向的输入流中的下一个字符。如果发生读取错误,则设置流的错误指示符,并且fgetc函数返回EOF。
本文涵盖了从开放标准输入读取的所有情况(成功,文件结束和读取错误),但它们并未涉及由于fclose
而关闭流的情况。我在标准中找不到任何涉及此案例的内容,这意味着案例未定义。
结论:在std::cin
之后从fclose(stdin)
读取,没有任何进一步的freopen
是不确定的行为。尝试读取已关闭的C流可能会引用已释放的资源。