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.