在freopen(..,“ r”,stdin)+ fclose(stdin)之后,进一步的std :: cin不起作用

时间:2019-03-21 02:45:41

标签: c++ file cin fclose freopen

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)在这里没有功能。

1 个答案:

答案 0 :(得分:0)

根据c++ draft 27.4.2

  

对象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流可能是指释放的资源。