13.5. scanf(), fscanf()

Read formatted string, character, or numeric data from the console or from a file.

Prototypes

#include <stdio.h>

int scanf(const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);

Description

The scanf() family of functions reads data from the console or from a FILE stream, parses it, and stores the results away in variables you provide in the argument list.

The format string is very similar to that in printf() in that you can tell it to read a "%d", for instance for an int. But it also has additional capabilities, most notably that it can eat up other characters in the input that you specify in the format string.

But let's start simple, and look at the most basic usage first before plunging into the depths of the function. We'll start by reading an int from the keyboard:

int a;

scanf("%d", &a);

scanf() obviously needs a pointer to the variable if it is going to change the variable itself, so we use the address-of operator to get the pointer.

In this case, scanf() walks down the format string, finds a "%d", and then knows it needs to read an integer and store it in the next variable in the argument list, a.

Here are some of the other percent-codes you can put in the format string:

%d

Reads an integer to be stored in an int. This integer can be signed.

%f (%e, %E, and %g are equivalent)

Reads a floating point number, to be stored in a float.

%s

Reads a string. This will stop on the first whitespace character reached, or at the specified field width (e.g. "%10s"), whichever comes first.

And here are some more codes, except these don't tend to be used as often. You, of course, may use them as often as you wish!

%u

Reads an unsigned integer to be stored in an unsigned int.

%x (%X is equivalent)

Reads an unsigned hexidecimal integer to be stored in an unsigned int.

%o

Reads an unsigned octal integer to be stored in an unsigned int.

%i

Like %d, except you can preface the input with "0x" if it's a hex number, or "0" if it's an octal number.

%c

Reads in a character to be stored in a char. If you specify a field width (e.g. "%12c", it will read that many characters, so make sure you have an array that large to hold them.

%p

Reads in a pointer to be stored in a void*. The format of this pointer should be the same as that which is outputted with printf() and the "%p" format specifier.

%n

Reads nothing, but will store the number of characters processed so far into the next int parameter in the argument list.

%%

Matches a literal percent sign. No conversion of parameters is done. This is simply how you get a standalone percent sign in your string without scanf() trying to do something with it.

%[

This is about the weirdest format specifier there is. It allows you to specify a set of characters to be stored away (likely in an array of chars). Conversion stops when a character that is not in the set is matched.

For example, %[0-9] means "match all numbers zero through nine." And %[AD-G34] means "match A, D through G, 3, or 4".

Now, to convolute matters, you can tell scanf() to match characters that are not in the set by putting a caret (^) directly after the %[ and following it with the set, like this: %[^A-C], which means "match all characters that are not A through C."

To match a close square bracket, make it the first character in the set, like this: %[]A-C] or %[^]A-C]. (I added the "A-C" just so it was clear that the "]" was first in the set.)

To match a hyphen, make it the last character in the set: %[A-C-].

So if we wanted to match all letters except "%", "^", "]", "B", "C", "D", "E", and "-", we could use this format string: %[^]%^B-E-].

So those are the basics! Phew! There's a lot of stuff to know, but, like I said, a few of these format specifiers are common, and the others are pretty rare.

Got it? Now we can go onto the next--no wait! There's more! Yes, still more to know about scanf(). Does it never end? Try to imagine how I feel writing about it!

So you know that "%d" stores into an int. But how do you store into a long, short, or double?

Well, like in printf(), you can add a modifier before the type specifier to tell scanf() that you have a longer or shorter type. The following is a table of the possible modifiers:

h

The value to be parsed is a short int or short unsigned. Example: %hd or %hu.

l

The value to be parsed is a long int or long unsigned, or double (for %f conversions.) Example: %ld, %lu, or %lf.

L

The value to be parsed is a long long for integer types or long double for float types. Example: %Ld, %Lu, or %Lf.

*

Tells scanf() do to the conversion specified, but not store it anywhere. It simply discards the data as it reads it. This is what you use if you want scanf() to eat some data but you don't want to store it anywhere; you don't give scanf() an argument for this conversion. Example: %*d.

Return Value

scanf() returns the number of items assigned into variables. Since assignment into variables stops when given invalid input for a certain format specifier, this can tell you if you've input all your data correctly.

Also, scanf() returns EOF on end-of-file.

Example

int a;
long int b;
unsigned int c;
float d;
double e;
long double f;
char s[100];

scanf("%d", &a);  // store an int
scanf(" %d", &a); // eat any whitespace, then store an int
scanf("%s", s); // store a string
scanf("%Lf", &f); // store a long double

// store an unsigned, read all whitespace, then store a long int:
scanf("%u %ld", &c, &b);

// store an int, read whitespace, read "blendo", read whitespace,
// and store a float:
scanf("%d blendo %f", &a, &d);

// read all whitespace, then store all characters up to a newline
scanf(" %[^\n]", s);

// store a float, read (and ignore) an int, then store a double:
scanf("%f %*d %lf", &d, &e);

// store 10 characters:
scanf("%10c", s);

See Also

sscanf(), vscanf(), vsscanf(), vfscanf()