0
votes

For example, when I do scanf("%s",arg); : Terminal allows me to input text until a newline is encountered but it only stores up to the first space character inside the arg variable. Rest remains in buffer.

scanf("%c", arg); : In this case also it allows me to enter text into the terminal till I give a newline character, but only one is stored in arg while the rest remains in buffer.

scanf("%[^P]", arg); : In this case, I can enter text into the terminal even after giving it a newline character until I hit a line with 'P' in it and press enter key (newline character) and then transfers everything to the input buffer.

How is it determined how much data from the input stream is to be transferred to the input buffer at a time?

Assuming that arg is of the proper type.

My understanding seems to be fundamentally wrong here. If someone can please explain this stuff, I will be very grateful.

3
There are a lot more layers involved here. gnome-terminal-server -> ptmx -> kernel -> pts -> your process's read() call -> libc buffering -> scanf() - Jonathon Reinhart
keyboard-electrical-contact -> keyboard-matrix-scanner -> usb-interface -> keyboard-driver -> gnome-terminal-server -> ... - and I've probably missed quite a few as well :-) - paxdiablo

3 Answers

2
votes

How is it determined? It's determined by the format string itself.

The scanf function will read items until they no longer match the format specifier given. Then it stops, leaving the first "non-compliant" character still in the buffer.

If you mean "how is it handled under the covers?", that's a different issue.

My first response to that is "it doesn't matter". The ISO standard mandates how the language works, and it describes a "virtual machine" capable of doing that. Provided you follow the rules of the machine, you don't need to worry about how things happen under the covers.

My second answer is probably more satisfying but is very implementation dependent.

For efficiency, the underlying software will probably not deliver any data to the implementation until it has a full line (though this of course is likely to be configurable, such as setting raw mode for the terminal). That means things like backspace may change the characters already entered rather than being inserted into the stream.

It may (such as with the GNU readline() library allow all sorts of really fancy editing on the line before delivering the characters. There's nothing to stop the underlying software from even opening up a vim session to allow you to enter data, and only deliver it once you exit :-)

1
votes

the buffer and primitive editing features are provided by the operating system. if you can set the terminal into "raw mode" you will see different behavior.

eg: characters may be available to read before enter is pressed especially if the buffer can also be disabled.

1
votes

I think, it is not related with how much, rather, what the format specifier tells.

As per C99, chapter 7.19.6.2, paragraph 2, (for fscanf())

The fscanf function reads input from the stream pointed to by stream, under control of the string pointed to by format that specifies the admissible input sequences and how they are to be converted for assignment, using subsequent arguments as pointers to the objects to receive the converted input.

And for the format specifiers, you need to refer to paragraph 12.