scanf – C Examples

Reading data from standard input can be achieved using scanf. Scanf allows the user to read data as a specific format, in c this includes string, char, int, double, hexadecimal characters.

This post will outline the basic uses of scanf, and how to read data based on the format you need. Alternatively, if you are curious how to output different variable types I have an article for using fprintf.

scanf definition

The definition of the scanf function is:

int scanf(const char *format, ...);

Using scanf

Okay, now you see the definition of scanf, how do you use it?! The format argument is the most important piece of this puzzle. If you are requesting user input as say someones name, it would make sense that this is a string or character array, and thus it would make sense to use %s indicating you are expecting a string. Alternatively, if you know you are reading in a decimal value the format specifier should probably be %d for decimal.

Lets get down to business. Here is a little program that reads in various inputs using scanf including scanf for a string, scanf for a char and a few others. This example includes the use of fprintf.

Note: The whitespace character with the scanf function will read and ignore any whitespace characters (this includes blank spaces and the newline and tab characters) which are encountered before the next non-whitespace character. This includes any quantity of whitespace characters, or none.

#include <stdio.h>
 
int main(int argc, char **argv)
{
  char input_array[100];
  int i; 
  double d;
 
  fprintf(stdout, "Enter your name: ");
  scanf("%s",input_array);  
 
  fprintf(stdout, "Enter a decimal value between 1 and 100: ");
  scanf("%d",&i);
 
  fprintf(stdout, "Name: %s , %d is between 1 and 100.\n",input_array,i);
 
  fprintf(stdout, "Enter a hexadecimal number: ");
  scanf("%x",&i);
  fprintf(stdout, "You have entered %#x (%d).\n",i,i);
 
  return 0;
}

Compiling and running the program we get:

erik@debian:~/scanf_ex$ ./scanf_ex
Enter your name: Erik
Enter a decimal value between 1 and 100: 45
Name: Erik , 45 is between 1 and 100.
Enter a hexadecimal number: beef
You have entered 0xbeef (48879).

Voila, not much too it really. The important thing to note is the use of the format specifier.

scanf Format Specifiers

The power of scanf lays in its ability to read in input as a specific format. This is especially useful in C because C has so many types.

Format specifiers as outlined in the scanf manual page:

h – Indicates that the conversion will be one of diouxX or n and the next pointer is a pointer to a short int or unsigned short int (rather than int).

hh – As for h, but the next pointer is a pointer to a signed char or unsigned char.

j – As for h, but the next pointer is a pointer to a intmax_t or uintmax_t. This modifier was introduced in C99.

l – Indicates either that the conversion will be one of diouxX or n and the next pointer is a pointer to a long int or unsigned long int (rather than int), or that the conversion will be one of efg and the next pointer is a pointer to double (rather than float). Specifying two l characters is equivalent to L. If used with %c or %s the corresponding parameter is considered as a pointer to a wide character or wide character string respectively.

L – Indicates that the conversion will be either efg and the next pointer is a pointer to long double or the conversion will be dioux and the next pointer is a pointer to long long.

q – equivalent to L. This specifier does not exist in ANSI C.

t – As for h, but the next pointer is a pointer to a ptrdiff_t. This modifier was introduced in C99.

z – As for h, but the next pointer is a pointer to a size_t. This modifier was introduced in C99.

The following conversion specifiers are available:

% – Matches a literal %. That is, %% in the format string matches a single input % character. No conversion is done, and assignment does not occur.

d – Matches an optionally signed decimal integer; the next pointer must be a pointer to int.

D – Equivalent to ld; this exists only for backwards compatibility. (Note: thus only in libc4. In libc5 and glibc the %D is silently ignored, causing old programs to fail mysteriously.)

i – Matches an optionally signed integer; the next pointer must be a pointer to int. The integer is read in base 16 if it begins with 0x or 0X, in base 8 if it begins with 0, and in base 10 otherwise. Only characters that correspond to the base are used.

o – Matches an unsigned octal integer; the next pointer must be a pointer to unsigned int.

u – Matches an unsigned decimal integer; the next pointer must be a pointer to unsigned int.

x – Matches an unsigned hexadecimal integer; the next pointer must be a pointer to unsigned int.

X – Equivalent to x.

f – Matches an optionally signed floating-point number; the next pointer must be a pointer to float.

e – Equivalent to f.

g – Equivalent to f.

E– Equivalent to f.

a – (C99) Equivalent to f.

s – Matches a sequence of non-white-space characters; the next pointer must be a pointer to character array that is long enough to hold the input sequence and the terminating null character (\0), which is added automatically. The input string stops at white space or at the maximum field width, whichever occurs first.

c – Matches a sequence of characters whose length is specified by the maximum field width (default 1); the next pointer must be a pointer to char, and there must be enough room for all the characters (no terminating null byte is added). The usual skip of leading white space is suppressed. To skip white space first, use an explicit space in the format.

scanf Return Value

These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure.

The value EOF is returned if the end of input is reached before either the first successful conversion or a matching failure occurs. EOF is also returned if a read error occurs, errno is set if this occurs.