6

When I redirect a file to stdin using MyProgram < cl.txt command from the command line, scanfs doesn't wait me to press Enter.

But when I use scanf in my program without doing so, it does block until enter key is pressed.

How exactly does it determine that? Does it keep reading the stream until \n is encountered? or does it really wait me to press a key?

When I don't write anything and press Enter it doesn't stop blocking either and keeps asking. I'm really confused.

Spikatrix
  • 20,225
  • 7
  • 37
  • 83
Millo Varantz
  • 173
  • 2
  • 8

3 Answers3

8

Does it keep reading the stream until '\n' is encountered?

Normally stdin is in line buffering mode (_IOLBF, see setvbuf). Whenever the buffer is empty, stdin waits for a whole new line to be entered, i.e. waits until you press Enter and \n is inserted into the buffer:

On Input, the buffer is filled up to the next newline character when an input operation is requested and the buffer is empty.

Note: the console (terminal) is most often implementing a buffering on its own, and does not send any data to the stream until you press Enter - this allows you to edit the data (like use delete, and backspace keys) before you send them to the application. Therefore even with no buffering on the stdin side (like when you perform setvbuf(stdin, NULL, _IONBF, 0)), the scanf may still wait until the Enter is pressed.

Suma
  • 33,181
  • 16
  • 123
  • 191
7

scanf is just reading from its input stream. If the input stream is a pipe, and the other end of that pipe is associated with a tty (which is usually the case if you are interactively entering data by pressing keys on a keyboard), scanf will return as soon as it reads data that completes its format string (or fails to match it). The tty, however, if it is in cooked mode (which is the default, and unless you make some effort to put the tty into raw mode, you should assume it is cooking what you type), will not write any data into the pipe until you hit return.

In other words, it's not your scanf that is blocking. (Well, it is blocking, but it's not the source of the experienced delay.) Rather, the tty driver is waiting for you to hit return before it passes any data to your program.

William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • When I press enter without typing anything is it operating system that ignores that input or is it scanf itself? – Insignificant Person May 23 '15 at 07:44
  • @InsignificantPerson I do not think scanf ignores the input, it only wants more input, and as there are no more data in the input buffer, stdin blocks until the data arrive. – Suma May 23 '15 at 09:44
  • 1
    @InsignificantPerson It depends on the format string, but often format strings are such that scanf ignores leading whitespace. In that case, your solitary newline is read (but ignored) as scanf continues looking for data to match the format string. – William Pursell May 23 '15 at 13:54
3

When you call scanf it immediately waits for input. in your first example, input is provided in the form of "cl.txt". In your second example, no input is provided until you press a key. Synchronous IO will block on its executing thread until it receives input.

Mitch Connor
  • 766
  • 10
  • 19