More on printf & scanf Format Specifiers

There are several format specifiers - the one you use should depend on the type of the variable you wish to print out. Here are the common ones:

Format Specifier

Type

%d (or %i)

int

%c

char

%f

float

%lf

double

%s

string

%x hexadecimal

To display a number in scientific notation, use %e. To display a percent sign, use %%.

%d is essentially the same as %i but I used %d from the very first day. LF stands for "long float".



Warning

Don't try to display a (decimal) float/double number using the integer format specifier, %d, as this displays unexpected values! Similarly, don't use %f for displaying integers. Mixing %d with char variables, or %c with int variables is all right, as shown in this example:

#include <stdio.h>

int main() {
  int a = 72;
  char b = 'A';
  printf("a equals %d \n", a);
  printf("a equals %c \n", a);
  printf("b equals %d \n", b);
  printf("b equals %c \n", b);
}

a equals 72
a equals H
b equals 65
b equals A

The reason why this works is because a character constant is just an integer from 0 to 255.



Two or More Format Specifiers

You could use as many format specifiers as you want with printf - just as long as you pass the correct number of arguments.

The ordering of the arguments matters. The first one should correspond to the first format specifier in the string and so on. Take this example:

printf("a=%d, b=%d, c=%d\n", a,b,c);

If a, b and c were integers, this statement will print the values in the correct order. Rewriting the statement as...

printf("a=%d, b=%d, c=%d\n", c,a,b);

... would still cause the program to compile OK, but the values of a, b and c would be displayed in the wrong order!



Minimum Field Width

Suppose you want the program to display output that occupies a minimum number of spaces on the screen. You can achieve this by adding an integer value after the percent sign of a format specifier.

For example, if you want to display an integer using a minimum of 8 spaces, you'd write %8d in your printf statement.

This example gives a demonstration:

 
#include <stdio.h>
 
int main() {
  int x = 123;
	
  printf("Printing 123 using %%0d displays %0d\n", x);
  printf("Printing 123 using %%1d displays %1d\n", x);
  printf("Printing 123 using %%2d displays %2d\n", x);
  printf("Printing 123 using %%3d displays %3d\n", x);
  printf("Printing 123 using %%4d displays %4d\n", x);
  printf("Printing 123 using %%5d displays %5d\n", x);
  printf("Printing 123 using %%6d displays %6d\n", x);
  printf("Printing 123 using %%7d displays %7d\n", x);
  printf("Printing 123 using %%8d displays %8d\n", x);
  printf("Printing 123 using %%9d displays %9d\n", x);
	
  return 0;
}

Output:

Printing 123 using %0d displays 123
Printing 123 using %1d displays 123
Printing 123 using %2d displays 123
Printing 123 using %3d displays 123
Printing 123 using %4d displays  123
Printing 123 using %5d displays   123
Printing 123 using %6d displays    123
Printing 123 using %7d displays     123
Printing 123 using %8d displays      123
Printing 123 using %9d displays       123

Notice that in the first 4 cases, 123 is displayed in the same way as when you normally use %d. Why? Simple - the number of spaces on the screen that 123 can be displayed is greater than or equal to 3.

But also, if you write %09d, the program will display zeros before the number itself. In the above example, it will display:

Printing 123 using %09d displays 000000123

An advantage of using this, is that you can count the minimum field of the number!



More Precision

You can gain more control with the displaying of integers by placing a dot, followed by an integer, after the minimum field specifier. The dot and this integer is known as a PRECISION SPECIFIER.

The integer you add specifies the maximum field width when displaying an integer or string.

If you're using %f, the format specifier for floating point numbers, you can control the number of decimal places that is displayed (which is 6 by default). How? By using the precision specifier. This time, the number after the dot is the number of decimal places. The number before the dot is still the minimum field width.

This example should help clarify things:

 
#include <stdio.h>
 
int main() {
  float x = 3.141592;
  
  printf("Printing 3.141592 using %%f \t displays %f\n", x);
  printf("Printing 3.141592 using %%1.1f \t displays %1.1f\n", x);
  printf("Printing 3.141592 using %%1.2f \t displays %1.2f\n", x);
  printf("Printing 3.141592 using %%3.3f \t displays %3.3f\n", x);
  printf("Printing 3.141592 using %%4.4f \t displays %4.4f\n", x);
  printf("Printing 3.141592 using %%4.5f \t displays %4.5f\n", x);
  printf("Printing 3.141592 using %%09.3f   displays %09.3f\n", x);
  printf("Printing 3.141592 using %%-09.3f  displays %-09.3f\n", x);
  printf("Printing 3.141592 using %%9.3f    displays %9.3f\n", x);
  printf("Printing 3.141592 using %%-9.3f   displays %-9.3f\n", x);
  
  return 0;
}

Output:

Printing 3.141592 using %f       displays 3.141592
Printing 3.141592 using %1.1f    displays 3.1
Printing 3.141592 using %1.2f    displays 3.14
Printing 3.141592 using %3.3f    displays 3.142
Printing 3.141592 using %4.4f    displays 3.1416
Printing 3.141592 using %4.5f    displays 3.14159
Printing 3.141592 using %09.3f   displays 00003.142
Printing 3.141592 using %-09.3f  displays 3.142
Printing 3.141592 using %9.3f    displays     3.142
Printing 3.141592 using %-9.3f   displays 3.142

You may have noticed that if you use a negative value for the minimum width specifier, the output will not be affected by a zero after the minus sign.

Also, in the case for decimal numbers, the decimal point occupies a character space on the screen.



scanf

If you have multiple format specifiers within the string argument of scanf, you can input multiple values. All you need to do is to separate each format specifier with a DELIMITER - a string that separates variables. For convenience, the delimiter should be one character that's a punctuation mark, like a comma or a space. As a default, scanf stops reading in a value when space, tab or Enter is pressed.

Consider scanf("%d %d", &x, &y);

(Assume that x and y have been declared beforehand!).

If I entered: 1 2 and pressed Enter, 1 would get assigned to x, and 2 would get assigned to y.

But if I entered 1, 2 and pressed Enter, x would equal 1, but y won't get assigned 2 because scanf was not expecting a comma in the input string.

Now consider:

scanf("%d, %d, %d", &x,&y,&z);

If I entered 1 2 3 and pressed enter 1 would get assigned to x but 2 and 3 won't get assigned to y or z, simply because I didn't separate the numbers with commas.

Entering 1,2,3 works, but why does 1, 2, 3 also work? scanf ignores spaces, tabs and carriage returns immediately after the delimiters.

Just don't put a space, tab or carriage return before the delimiter! 1 ,2, 3 won't work.

If you want the user to press return after each number, try something along the lines as:

scanf("%d\n%d\n%d", &x,&y,&z);

Note that you shouldn't put a delimiter after the last format specifier!



Tip

This is probably past the novice stage, but if you wanted to enter a value for a double variable using scanf, you need to use %lf as the format specifier - it's the specifier for a long float variable.