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

问题描述 投票:0回答:1
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)在这里没有任何功能。

c++ file cin fclose freopen
1个回答
0
投票

根据c++ draft 27.4.2

对象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流可能会引用已释放的资源。

© www.soinside.com 2019 - 2024. All rights reserved.