How to Format with printf() in C Programming

By Dan Gookin

The most popular output function in C programming has to be printf(). It’s everyone’s favorite. It’s one of the first functions you learn in C. And as one of the most complex, it’s one of the functions that no one ever fully knows.

The power in printf() lies in its formatting string. That text can be packed with plain text, escape sequences, and conversion characters, which are the little percent goobers that insert values into the text output. It’s those conversion characters that give printf() its real power, and they’re also one of the function’s least understood aspects.

How to format floating point

You can use more than the basic %f conversion character to format floating-point values. In fact, here’s a great format you can use in the printf() function’s formatting text:

The w sets the maximum width of the entire number, including the decimal place. The p sets precision. For example:


This statement outputs four spaces and then 12.45. Those four spaces plus 12.45 (five characters total) equal the 9 in the width. Only two values are shown to the right of the decimal because .2 is used in the %f conversion character.

It’s possible to specify the precision value without setting a width, but it must be prefixed by the decimal point, as in %.2f (percent point-two F). See The printf() Floating-Point Formatting Gamut.


#include <stdio.h>
int main()
 float sample1 = 34.5;
 float sample2 = 12.3456789;
 printf("%%9.1f = %9.1fn",sample1);
 printf("%%8.1f = %8.1fn",sample1);
 printf("%%7.1f = %7.1fn",sample1);
 printf("%%6.1f = %6.1fn",sample1);
 printf("%%5.1f = %5.1fn",sample1);
 printf("%%4.1f = %4.1fn",sample1);
 printf("%%3.1f = %3.1fn",sample1);
 printf("%%2.1f = %2.1fn",sample1);
 printf("%%1.1f = %1.1fn",sample1);
 printf("%%9.1f = %9.1fn",sample2);
 printf("%%9.2f = %9.2fn",sample2);
 printf("%%9.3f = %9.3fn",sample2);
 printf("%%9.4f = %9.4fn",sample2);
 printf("%%9.5f = %9.5fn",sample2);
 printf("%%9.6f = %9.6fn",sample2);
 printf("%%9.7f = %9.7fn",sample2);
 printf("%%9.6f = %9.6fn",sample2);
 printf("%%9.7f = %9.7fn",sample2);
 printf("%%9.8f = %9.8fn",sample2);

Exercise 1: Type the source code from The printf() Floating-Point Formatting Gamut into your editor. It looks like a lot of work, but you can create the code quickly by using a lot of copy-and-paste.

The output from Exercise 1 helps illustrate the width and precision portions of the %f conversion character’s output:

%9.1f = 34.5
%8.1f = 34.5
%7.1f = 34.5
%6.1f = 34.5
%5.1f = 34.5
%4.1f = 34.5
%3.1f = 34.5
%2.1f = 34.5
%1.1f = 34.5
%9.1f = 12.3
%9.2f = 12.35
%9.3f = 12.346
%9.4f = 12.3457
%9.5f = 12.34568
%9.6f = 12.345679
%9.7f = 12.3456793
%9.8f = 12.34567928

From this output, you can see how the width value “pads” the numbers on the left. As the width value decreases, so does the padding. However, when the width specified is wider than the original value, nonsense is displayed, as shown by the last two lines of output. That’s because the width is beyond the limit of single precision.

Setting the output width

The w option used to output width is available to all the conversion characters, not just %f. The width is the minimum amount of space provided for output. When the output is less than the width, it’s right-justified. When the output is greater than the width, the width is ignored. See Messing with the Width.


#include <stdio.h>
int main()
 printf("%%15s = %15sn","hello");
 printf("%%14s = %14sn","hello");
 printf("%%13s = %13sn","hello");
 printf("%%12s = %12sn","hello");
 printf("%%11s = %11sn","hello");
 printf("%%10s = %10sn","hello");
 printf(" %%9s = %9sn","hello");
 printf(" %%8s = %8sn","hello");
 printf(" %%7s = %7sn","hello");
 printf(" %%6s = %6sn","hello");
 printf(" %%5s = %5sn","hello");
 printf(" %%4s = %4sn","hello");

Exercise 2: Type the source code from Messing with the Width into a new project. Build and run to examine the output, which looks like this:

%15s = hello
%14s = hello
%13s = hello
%12s = hello
%11s = hello
%10s = hello
 %9s = hello
 %8s = hello
 %7s = hello
 %6s = hello
 %5s = hello
 %4s = hello

As with the width option for floating-point numbers (see the preceding exercise), space is padded on the left when the width is greater than the string displayed. But when the width is less than the string’s length, the full string is still displayed.

When the width value is specified for an integer, it can be used to right-align the output. For example:


This statement ensures that the output for value is right-justified and at least four characters wide. If value is fewer than four characters wide, it’s padded with spaces on the left. That is, unless you stick a 0 in there:


In that case, the printf() function pads the width with zeros to keep everything four characters wide.

How to align output

The width value in the conversion character aligns output to the right, known as right justification. But not everything is all right. Sometimes, you want left justification. To force the padding to the right side of the output, insert a minus sign before the width value in the %s conversion character. For example:


This statement displays the text in the array string justified to the left. If string is shorter than 15 characters, spaces are added to the right.

The source code in Meeting in the Middle displays two strings. The first one is left-justified within a range of varying widths. The width gets smaller with each progressive printf() statement.


#include <stdio.h>
int main()
 printf("%-9s men","meet");
 printf("%-8s men","meet");
 printf("%-7s men","meet");
 printf("%-6s men","meet");
 printf("%-5s men","meet");
 printf("%-4s men","meet");

Exercise 3: Copy the code form Meeting in the Middle into your editor. Create the program and run it to see the alignment output demonstrated.

Exercise 4: Write a program that displays the first and last names of the first four presidents of the United States. Store the names in a multidimensional char array. The names need to line up so that the output looks like this:

George Washington
John Adams
Thomas Jefferson
James Monroe