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)在这里没有功能。
答案 0 :(得分:0)
对象cin控制来自与在
中声明的对象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函数从流指向的输入流中返回下一个字符。 如果发生读取错误,将设置流的错误指示符并使用fgetc函数 返回EOF。
本文涵盖从打开的stdin读取的所有情况(成功,文件结束和读取错误),但它们未涉及由于fclose
而关闭流的情况。我在涵盖这种情况的标准中找不到任何内容,这意味着该情况是不确定的。
结论:在std::cin
之后从fclose(stdin)
进行读取,而没有其他freopen
的读取是未定义的行为。尝试读取封闭的C流可能是指释放的资源。