0

My question pertains to using a file descriptor which could be stdin or an opened file.

I am trying to figure out:

  1. Under what conditions does reading from a stream cause stalling. Why does cin >> x wait for user input, but fgets(line, len, file) on an opened file never stalls to my knowledge. (I know stalling would not make sense for reading a file, but I'm trying to figure out how streams work here.)
  2. How do you detect the end of the stream for opened file versus Stdin? It seems like when you read from Stdin, if you're at the end, it waits for input. If read from a file and you're at the end, a EOF is triggered somehow and it doesn't stall. And I think end of stream for Stdin would not necessarily mean the end of input, just that the program has read all available input so far, right?
Thomas
  • 6,032
  • 6
  • 41
  • 79
  • C tag is not relevant, behavior of `fgets()` could be different between C and C++. – Stargateur Jun 19 '17 at 23:15
  • `fgets` can block if the `file` argument is `stdin` (for example), or indeed simply if the underlying I/O device blocks. – Oliver Charlesworth Jun 19 '17 at 23:16
  • Any concrete test case that triggers _stalling_? You already know about [Why is iostream::eof inside a loop condition considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong)? – πάντα ῥεῖ Jun 19 '17 at 23:20
  • @Stargateur - Although the C++ standard delegates to the C standard for ``... – Oliver Charlesworth Jun 19 '17 at 23:20
  • That's because stdin doesn't have an end. (Unless it's coming from a file) – user253751 Jun 19 '17 at 23:22
  • @immibis - It does if the other end closes, no? – Oliver Charlesworth Jun 19 '17 at 23:24
  • @OliverCharlesworth This is strange because cppreference has a documentation c++ and c separate for [`fgets()`](http://en.cppreference.com/w/cpp/io/c/fgets). But still I prefer remove C tag when a question talk about the difference between `std::cin` and `std::fgets()`. – Stargateur Jun 19 '17 at 23:26
  • Reading from a hard disk will stall waiting for the hard disk, reading from the network will stall waiting for the network, and reading from a human will stall waiting for the human. – user253751 Jun 19 '17 at 23:49

1 Answers1

3

Fundamentally there's no difference between reading using cin (or another istream) vs. fgets (or fscanf, etc.)

In both cases, if you read from standard input, they'll stall waiting for input, and return EOF when they receive the correct indication that standard input has reached end of file (e.g., ctrl+d on Linux, ctrl+z or F6 on Windows). Of course, if standard input is redirected to a file, the program will sense end of file just like it normally would.

Likewise, in both cases, they actually are stalling while reading data from a file on disk--but at least in a typical case, the still be on the order of tens of milliseconds, so a person typically won't perceive it. Nonetheless, yes, when the CPU issues a read command to the drive controller, there's an extremely long pause (in terms of number of CPU clock cycles) before the data arrives from the disk drive. In a few cases, you can get long enough delays when reading from a file that they become human perceptible, or could even involve human intervention. It's pretty rare now, but once upon a time, reading a particular file could involve something like an operator mounting a tape.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111