scanf() cookbook

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.

Advertisements