for some simple HW code I wrote I needed to get 7 arguments via the scanf function:
scanf("%d %d %d %d\n", &vodka, &country, &life, &glut);
scanf("%d\n", &ageof);
scanf("%d\n", &dprice);
scanf("%d\n", &mprice);
as you can see, I'm asking for 7 arguments in this order:
argument [space] argument [space] argument [space] argument (down line)
argument (down line)
argument (down line)
argument (down line)
BUT, when running the code, I'm suddenly required to input 8 of them, and I have no idea why....
any help anyone?
As explained by @chqrlie and @Blue Moon a white space in the format, be it ' '
, '\n'
, '\n'
or any white-space does the same thing. It directs scanf()
to consume white-space, such as '\n'
from an Enter, until non-white-space is detected. That non-white-space character is then put back into stdin
for the next input operation.
scanf("%d\n", ...)
does not return until some non-white space is entered after the int
. Hence the need for the 8th input. That 8th input is not consumed, but available for subsequent input.
The best way to read the 4 lines of input is to .... drum roll ... read 4 lines. Then process the inputs.
char buf[4][80];
for (int i=0; i<4; i++) {
if (fgets(buf[i], sizeof buf[i], stdin) == NULL) return Fail;
}
if (sscanf(buf[0], "%d%d%d%d", &vodka, &country, &life, &glut) != 4) {
return Fail;
}
if (sscanf(buf[1], "%d", &ageof) != 1) {
return Fail;
}
if (sscanf(buf[2], "%d", &dprice) != 1) {
return Fail;
}
if (sscanf(buf[3], "%d", &mprice) != 1) {
return Fail;
}
// Use vodka, country, life, glut, ageof, dprice, mprice
return Success
When you have a whitespace in the format string, you tell scanf()
to ignore any number of whitespace characters. So the spaces you have between the %d
requires to input a non-whitespace char(s) which are consumed for each of the subsequent %d
.
The effect of spaces and \n
in the following scanf() calls you have isn't quite obvious. But the newline character at the end of each last scanf()
forces you to input a non-whitespace char. Hence, it looks like scanf()
requires an extra input.
However, you don't really any whitespace characters here as %d
would always ignore whitespace characters. So simply remove all spaces and \n
characters from the format strings.
White space characters in the scanf
format string are directives that mean read white space characters until you get a non white space character. A trailing \n
in your format string causes scanf
to consume the linefeed that was typed by the user and to keep asking for input until a non white space character is seen, but is left in the input buffer.
To consume the \n
exactly, you can use this ugly scanf
format:
scanf("%d%*1[\n]", &mprice);
Or you can just remove the trailing \n and consume the character with getchar()
but be aware that neither of these approaches provide for exact matching of the input:
scanf("%d", &mprice);
getchar();