简体   繁体   中英

After freopen(..,“r”,stdin) + fclose(stdin), further std::cin doesn't work

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;
}

This block of code is to have a mixture of input from terminal and files. The first, second and third cin works fine, but the fourth failed. It seems that fclose(stdin) has no function here.

According to the c++ draft 27.4.2 :

The object cin controls input from a stream buffer associated with the object stdin, declared in <cstdio>.

Reading from std::cin is the same as reading from stdin . This means that after fclose(stdin) using std::cin is like calling scanf("%d", &a) .

This is exactly what happens in the third case, where fclose(stdin) is called before reading std::cin . In contrast, cases 1-3 the code reads std::cin before fclose(stdin) .

Reading from a closed stdin is possibly undefined. Here is what the c11 draft has to say about it:

7.21.7.1 The fgetc function

...

 int fgetc(FILE *stream); 

...

Returns: If the end-of-file indicator for the stream is set, or if the stream is at end-of-file, the end- of-file indicator for the stream is set and the fgetc function returns EOF. Otherwise, the fgetc function returns the next character from the input stream pointed to by stream. If a read error occurs, the error indicator for the stream is set and the fgetc function returns EOF.

This text covers all cases of reading from an open stdin (successful, end-of-file, and a read error), but they don't refer to the case when the stream is closed due to fclose . I could not find anything in the standard that covers this case, which means that the case is undefined.

Conclusion : reading from std::cin after fclose(stdin) , without any further freopen is undefined behavior. Trying to read a closed C stream might refer to freed resources.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM