I've been having a lot of problems trying to figure out how to use scanf()
. It seems to work fine with integers, being fairly straight forward scanf("%d", &i)
.
Where I am running into issues is using scanf()
in loops trying to read input. For example:
do {
printf("counter: %d: ", counter);
scanf("%c %c%d", &command, &prefix, &input);
} while (command != 'q');
When I enter in a validly structured input like c P101
, it seems to loop again before prompting me. This seems to happen even with a single:
scanf("%c", &c)
in a while loop. It'll do the loop twice before prompting me again. What is making it loop twice, and how do I stop it?
When I enter in less amount of input that programmatically wouldn't have another character or number such as q
, pressing enter seems to prompt me to enter more. How do I get scanf()
to process both single and double character entries?
When you enter "c P101
" the program actually receives "c P101\n
". Most of the conversion specifiers skip leading whitespace including newlines but %c
does not. The first time around everything up til the "\n
" is read, the second time around the "\n" is read into command
, "c
" is read into prefix
, and "P
" is left which is not a number so the conversion fails and "P101\n
" is left on the stream. The next time "P
" is stored into command, "1
" is stored into prefix, and 1
(from the remaining "01
") is stored into input with the "\n
" still on the stream for next time. You can fix this issue by putting a space at the beginning of the format string which will skip any leading whitespace including newlines.
A similiar thing is happening for the second case, when you enter "q
", "q\n
" is entered into the stream, the first time around the "q
" is read, the second time the "\n
" is read, only on the third call is the second "q
" read, you can avoid the problem again by adding a space character at the beginning of the format string.
A better way to do this would be to use something like fgets() to process a line at a time and then use sscanf() to do the parsing.
It's really broken! I didn't know it
#include <stdio.h>
int main(void)
{
int counter = 1;
char command, prefix;
int input;
do
{
printf("counter: %d: ", counter);
scanf("%c %c%d", &command, &prefix, &input);
printf("---%c %c%d---\n", command, prefix, input);
counter++;
} while (command != 'q');
}
counter: 1: a b1
---a b1---
counter: 2: c d2
---
c1---
counter: 3: e f3
---d 21---
counter: 4: ---e f3---
counter: 5: g h4
---
g3---
The output seems to fit with Robert's answer.
Once you have the string that contains the line. i.e. "C P101", you can use the parsing abilities of sscanf.
See: http://www.cplusplus.com/reference/clibrary/cstdio/sscanf.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With