Regarding fscanf
(and I assume similarly for scanf
), C17 7.21.6.2.9 states the following:
"An input item is read from the stream... An input item is defined as the longest sequence of input characters which does not exceed any specified field width and which is, or is a prefix of, a matching input sequence. The first character, if any, after the input item remains unread..."
Before reading this I had always assumed that the first character after the input item was read too, then pushed back. For example, if the input was 5X and the conversion specification was %d
, both the 5 and the X would be read but the X would be pushed back. However, the quote above seems to indicate that each successive character in the input stream is being "peeked" at before it is read, so the X would never be read in the first place and a push back would never be necessary. However, footnote 289 states that fscanf pushes back at most one input character onto the input stream. So I guess my question is about what all of this really means. Does "read" mean to remove a character from the stream or could it also mean to "peek" at a character without removing it?
CodePudding user response:
The pushback is not always necessary. For example, if the conversion specification is =
and the code reads three decimal digits successfully, it doesn't need to read anything more and there is no pushback.
The pushback is always the character that was read, so beyond recording where to read next, the input buffer doesn't need to change. (Using ungetc()
, you can unget (push back) a character other than the one that was read.)
Reading a character means logically removing it from the stream. If it isn't a usable character, it is pushed back, so the effect is the same as peeking.
CodePudding user response:
Input stream can push back at least 1 character.
Scanning "5X"
with "%d"
results in "5"
being read and converted to an int 5
, then saved. The "X"
is read, but pushed back.
Trouble occurs with input like "-a"
as the "-"
is read and so is "a"
. C guarantees a successful push-back of "a"
, but if "-"
is successfully pushed back depends on the implementation.
This is one of the reasons that it is better to read a line of user input with fgets()
into a string and then parse the string, than to use (f)scanf()
.