Capabilities of Format Specifiers
In the previous tutorial, we learned the basics of the printf()
function and explored how we can use it to display text with a bit of formatting. The focus of this tutorial is format specifiers, a.k.a. conversion specifications. We know what format specifiers are and how they can be used to format a text that we may want to display. We learned to use basic format specifiers like %d
or %c, but there is more to that. In this tutorial, we will go into the depths of the format specifiers and unlock their capabilities. So, let’s get into it.
The Syntax
Before moving forward, keep in mind that I may use the terms “format specifiers” and “conversion specifications” interchangeably. Consider them the same.
No matter what format specifier we pick, they all follow a syntax, and decoding that syntax will help us understand their capabilities. Here is the syntax:
%w.pX or %w.px
Here’s what each part of the syntax means:
w
(optional): represents the minimum field width.
p
(optional): represents precision.
X
or x
: represents the data type.
Following are the possible ways to write the format specifiers:
%5.2f // w = 5, p = 2
%10f // w = 10
%.4f // p = 4
Note for readers
The dot between w and p is acting as the separator between the two. If we do not specify the value for p, then there is no need to place the dot. But if we only specify p, then the dot is needed.
Let’s now properly understand these different parts.
Minimum Field Width
Minimum field width is an integer used to set the minimum number of characters to display on the screen. It can be positive or negative. If the minimum field width is set to a positive value and it is less than or equal to the number of characters to display, then the characters will be displayed as they are. For example, let’s say we want to display 4325 on the screen, and the minimum field width is set to 3; it will be displayed as it is.
#include <stdio.h>
int main() {
int var = 4325;
printf("%3d", var); // here 4 represents the minimum field width
return 0;
}
Output:
4325
We want to display a minimum of 3 characters; we have 4, so it will not cause a problem. But, if the minimum field width is set to, let’s say, 8, then 4 spaces will be added in front of the number (as we have fewer characters to display, the positions of the remaining characters are filled with spaces).
#include <stdio.h>
int main() {
int var = 4325;
printf("%8d", var); // here 4 represents the minimum field width
return 0;
}
Output:
4325
If the minimum field width is set to a negative value, then the spaces will be added towards the right:
#include <stdio.h>
int main() {
int var1 = 4325, var2 = 10;
printf("%-8d%d", var1, var2); // Added a new variable to make it clear that spaces are added in the right-hand side.
return 0;
}
Output:
4325 10
What’s the benefit?
We can use minimum field width to align items the way we want. As an example, let’s say we want to display the following table on the screen:
ID Name Marks
----------------------------------
1 Alice 89.24
2 Bob 95.60
3 Mike 78.90
4 Peter 85.67
5 Julie 37.50
The code is as follows:
#include <stdio.h>
int main() {
printf("%-10s %-15s %-10s\n", "ID", "Name", "Marks");
printf("----------------------------------\n");
printf("%-10d %-15s %-10.2f\n", 1, "Alice", 89.24);
printf("%-10d %-15s %-10.2f\n", 2, "Bob", 95.6);
printf("%-10d %-15s %-10.2f\n", 3, "Mike", 78.90);
printf("%-10d %-15s %-10.2f\n", 4, "Peter", 85.67);
printf("%-10d %-15s %-10.2f\n", 5, "Julie", 37.5);
return 0;
}
Focus on the first printf()
function
printf("%-10s %-15s %-10s\n", "ID", "Name", "Marks");
This function will help understanding the remaining code as well. In this printf()
function, the format specifier %-10s
will be replaced by the string “ID” at runtime. It has the minimum field width set to -10. This means the number of characters to be displayed must be at least 10. If not, then the remaining characters will be filled in by the spaces towards the right (because of the minus sign). In our example, the string “ID” has only 2 characters. The positions for the remaining 8 characters will be filled in by 8 spaces towards the right. Therefore, the next string will begin at the 11th position from the beginning (where the first 10 positions are occupied by the string “ID”). The similar thing can be observed for %-15s
, where the first four positions are occupied by the string “Name” and the remaining 11 positions are occupied by spaces. If you just print the result of the first printf()
function, you will observe the following output:
ID Name Marks
In this way, the header of the table can be displayed with appropriate spacing.
This alignment is followed by the data of the table as well. The minimum field width is set the same for all the data, and because of this, you will see the following output:
ID Name Marks
----------------------------------
1 Alice 89.24
2 Bob 95.60
3 Mike 78.90
4 Peter 85.67
5 Julie 37.50
So, with this example, it is clear how useful minimum field width can be to display a table-like format. You can use the minimum field width in creative ways to display data as you wish.
Challenge for you
Write a program to display the following pattern:
==== Right Aligned Pyramid ====
*
**
***
****
*****
******
⚠️ Try out this challenge on your own first, then compare it with the provided solution.
Solution:
#include <stdio.h>
int main() {
printf("==== Right Aligned Pyramid ====\n");
printf("%6s\n", "*");
printf("%6s\n", "**");
printf("%6s\n", "***");
printf("%6s\n", "****");
printf("%6s\n", "*****");
printf("%6s\n", "******");
return 0;
}
Precision
The minimum field width is well defined and has the same meaning for all the specifiers, but the meaning of precision changes from one format specifier to the other. Hence, it makes sense to discuss different format specifiers in the view of precision.
For different types of data, we have different format specifiers. We will discuss them as we encounter them in the upcoming tutorials. Some of the most common types and the meaning of precision for each are mentioned in the following table:
Specifier | Description | Meaning of Precision | Example |
---|
%d | signed decimal integer | minimum number of digits to display (padded with zeros in front if necessary) | If the value is 51, then %.4d will display 0051 |
%c | character | precision DOES NOT apply to single characters | %.xc, where x is some number, is invalid |
%f | decimal floating-point | number of digits after the decimal point | If the value is 3.14159, then %.2f displays 3.14. |
%lf | double-precision decimal floating-point | Same as %f | %.2lf displays 3.14 |
%e | exponential floating-point | number of digits after the decimal point (default is 6). | %.2e for the number 7845.903 displays 7.85e+03 (which is 7.85×10^3) |
%s | string | maximum number of characters to print. | %.4s prints a maximum of 4 characters. |
How is minimum field width different from precision in %d?
Minimum field width tells the overall width of the digits to display and is mainly used to align a number. If you want to pad a number with zeros in the beginning, then precision can be used.
For example, let’s say we want to display an 11-digit phone number where the first digit must be a zero (this is the convention followed in India for phone numbers). And we also want to align the number to the right by 1 space. This can be achieved using the following code:
#include <stdio.h>
int main() {
long phone = 9911778899;
printf("Phone Number:%12.11ld", phone);
return 0;
}
Output:
Phone Number: 09911778899
The phone number is automatically padded with a zero in front because the precision is set to 11. The minimum field width of 12 is used to display a minimum of 12 characters, where 11 characters are occupied by the number itself and 1 character is reserved for space.
Summary
- The syntax of a format specifier is
%w.px
w
= minimum field width
p
= precision
X
= conversion specifier (d, c, f, ld, etc.)
- The minimum field width (w) specifies the minimum number of characters to display
- Adds spaces to the left when w is positive.
- Adds spaces to the right when w is negative.
- Precision (p) has different meanings for different data types
%d
: minimum digits (padded with zeros in front)
%f
: digits after decimal point
%e
: digits after decimal point (exponential)
%s
: maximum count of characters
- Use field width and precision to
- create structured layouts
- to maintain readability of the code
- control padding
Review Questions
Q1. What will be the output of the following code?
#include <stdio.h>
int main() {
printf("%-10d", 123);
return 0;
}
a. 123
b. 123 (with 7 spaces to the left)
c. 123 (with 7 spaces to the right)
d. Error
Ans. Option (c), 123 with 7 spaces to the right, is the correct option. The minimum field width is set to 10, which means a minimum of 10 characters to display. We have 3 characters (123); the remaining 7 are spaces. They will be added to the right as the sign is minus.
Q2. Which of the following statements about precision in %f is correct?
a. Precision defines the total number of digits printed.
b. Precision specifies the number of digits after the decimal point.
c. Precision applies only when there is no decimal part.
d. Precision applies only when the number is an integer.
Ans. Option (b) is the correct option. Here is the reference. Check out the 3rd row in the table.
Q3. The syntax for a printf() format specifier is %w.pX. Here, w stands for ________ and p stands for _________.
Ans. The syntax for a printf() format specifier is %w.pX. Here, w stands for minimum field width and p stands for precision.
Q4. What will be printed by the following piece of code?
#include <stdio.h>
int main() {
printf("%8.2f", 255.9876);
return 0;
}
a. 255
b. 255.9876
c. 255.99 (with 3 spaces in front)
d. 255.99 (with 2 spaces in front)
Ans. Option (d) is the correct option. A minimum of 8 characters needs to be displayed, and there must be exactly 2 digits after the decimal point, so it is clear that 255.99 will be displayed. But, these are only 6 characters. Spaces will take the place of the remaining characters.
Q5. Which of the following is NOT valid?
a. %5d
b. %.4f
c. %.3c
d. %-10s
Ans. Option (c) is the correct option. Precision is not defined for single characters.
Q6. How many spaces will be displayed between 123 and 456 by the following code?
#include <stdio.h>
int main() {
printf("%-8d%d", 123, 456);
return 0;
}
a. 5
b. 4
c. 3
d. 2
Ans. Option (a) is the correct option. As the minimum field width is 8 for the first integer, a minimum of 8 characters needs to be displayed. There are only 3, so 5 spaces will be added towards the right. So, there will be a total of 5 spaces in between 123 and 456.
Leave a comment