I have been thinking scanf() awkward because I tried to understand scanf() as opposite to printf(). That was wrong in many ways.
- In scanf() format, a space is not necessary between two “%<conversion>”s. For example, format “%d%d” matches input “100 200″.
- In scanf() format, a space matches any number of any white space characters, such as tab and newline. For example, format “%d %d” matches input “100\n200″, format “%d\n%d” matches input “100 200″.
Once I learned that, scanf() started working as I expect. Here is some howto.
How to read data over newline:
input:
100
200
program:
scanf("%d%d", &i1, &i2);
printf("%d %d\n", i1, i2);
output:
100 200
scanf() does not care about the notion of line. “\n” is just one of the
white space character.
How to read data with leading white space:
input:
100
200
program:
scanf("%d%d", &i1, &i2);
printf("%d %d\n", i1, i2);
output:
100 200
“%<conversion>” skips the leading spaces.
In C++, istream (such as cin) skips the leading spaces in the same way.
How to skip until end of line:
input:
100 101 102
200 201 202
program:
scanf("%d%*[^\n]", &i1);
scanf("%d%*[^\n]", &i2);
printf("%d %d\n", i1, i2);
output:
100 200
“%*” throws away the matched string.
another way:
scanf("%d", &i1);
while (getchar() != '\n');
scanf("%d", &i2);
How to read various floating numbers:
input:
1 0.1 1e-2
program:
scanf("%f%f%f", &f1, &f2, &f3);
printf("%f %f %f\n", f1, f2, f3);
output:
1.000000 0.100000 0.010000
“%f” can read many formats.
How to skip lines that begins with comment character:
input:
# This is a comment.
# This is a comment.
# This is a comment.
string-data
program:
while (scanf(" #%[^\n]", s));
scanf("%s", s);
printf("%s\n", s);
output:
string-data
” ” before “#%[^\n]” matches zero or more spaces.
If ” #%[^\n]” doesn’t match, no input is consumed.