In this section, we will learn what the printf() function is and how to use it in C.
What is printf() Function in C?
We use the `printf` function to send formatted contents to the output stream, which by default will end up on the computer’s screen.
The prototype of `printf` function is declared in the `<stdio.h>` header file and so we need to include this header in the program if we want to use the function.
C printf() Function Syntax:
int printf(const char *format, …)
This function takes at least one argument and that first argument must be a character-string. So character string should always be presented as the first argument of the `printf` function.
Character-String is one or series of characters grouped together and terminated with a null character. One way to create them is by using the double-quotation `”` mark.
For example: “Hello” or “H” or “test” or “Life is beautiful”, etc. all of them are character-string.
Even with just two double quotations that follow each other, they represent a character-string.
For example: “”
You can learn more about it in the character string section.
C printf Function Return Value
As you can see, the printf function has a return type of `int`. It means every time we call this function; it returns a value of this type.
But what is the return value of this function?
It is the number of characters that this function sent to the output stream.
Example: using prinf() function in C
#include <stdio.h> int main() { printf("Life is beautiful"); return 0; }
Output:
Life is beautiful
In this example, the `printf` function took the character-string `Life is beautiful` as its argument and when we compiled and run the program, it printed the message on the screen.
Now, let’s say we have a variable of type `integer` with the name `age`. We want to print the value assigned to this variable and send it to the screen. How do you think this can be done?
You might guess by using the variable as the argument of the `printf` function like the example below:
#include <stdio.h> int main() { int age = 28; printf(age); return 0; }
Output:
warning: passing argument 1 of 'printf' makes pointer from integer without a cast [-Wint-conversion] printf(age);
The moment we compile this program; we will get the warning declared above.
OK, let’s see what the problem is:
As mentioned at the beginning of this section, the `printf` function takes at least one argument and that is a `character-string`. In the last example, we called the `printf` function but without assigning a `character-string` as its first argument! But we didn’t want to have the character-string! All we wanted was the value assigned to the `age` variable to be displayed on the screen.
Note: no-matter if we need the character-string or not, they should be presented as the first argument in the `printf` function.
These character-strings are also called control-string when used as the first argument of the `printf-function`.
Now, to send the value of a variable that holds an integer value, for example, we use the conversion- specifications.
Let’s see what they are and how to use them in C now.
C Format Specifiers (AKA conversion specifications)
Conversion- specifications are a set of notations that are used within the character strings.
For example:
"The age is: %d"
The notation `%d` is one of the many conversion- specifications supported in C.
We use them when we want to add more arguments to the `printf` function. You can think of these conversion- specifications as the placeholder for those arguments.
These notations are called Conversion-Specification because they specify how the rest of arguments we assign to the printf function must be converted and displayed on the output stream.
For example, the `%d` is the placeholder for integer values. These values can be variables of type integer, constant values of this type, or the result of an expression that is of type integer.
Example: printf format specifier and Integer value
#include <stdio.h> int main() { int age = 28; printf("The age is: %d", age); return 0; }
Output:
The age is: 28
In this example, within the character-string the `%d` notation is used and this is the placeholder for one argument of type integer.
For the argument, we used the `age` variable and so the value of this variable will replace the conversion-specification at runtime as the result of the example above showed.
Note: the number of format-specifier in the character-string should be equal to the number of arguments added to the `printf` function. For example, if we used 3 format-specifier in the character-string, we need to supply 3 more arguments of each of the same type related to its format-specifier in the character-string.
Example: using format-specifier with floating point
#include <stdio.h> int main() { int age = 28; double height = 6.2; printf("His age is: %d and his height is: %f inches", age, height); return 0; }
Output:
His age is: 28 and his height is: 6.200000 inches
In this example, we used 2 conversion specifications. The first one is the placeholder of integer values. And the second one is the placeholder of float type values (like `double` and `float`).
So, because we used two conversion- specifications, we need two arguments after the character-string to replace the %d and %f format-specifiers, respectively. That’s why we used the `age` variable as the first argument (it is of type integer) and set the second argument to `height` variable, which is of type `double`.
List of Format Specifiers in C
In the table below you can see the list of format- specifiers:
The table above is taken from the C Primer Plus, 6th Edition Book
Example: using format specifier in C
#include <stdio.h> int main() { int age = 28; double height = 6.2; char characterString[]= "inches"; printf("The age is: %d and the height is: %f%s", age,height,characterString); return 0; }
Output:
The age is: 28 and the height is: 6.200000inches
C Format Specifiers Modifiers:
At the beginning of this section, we mentioned that conversion-specifications are used to convert (translate) data into displayable form.
Sometimes, though, the way this conversion happens is not what we really want!
For example, take a look at the way conversion happens on a float data.
Example: format-specifiers without using Modifiers in C
#include <stdio.h> int main() { float height = 5.8; printf("The height is: %f", height); return 0; }
Output:
The height is: 5.800000
As you can see, the result has 5 leading 0s but in the `height` variable, there’s no such thing.
This is the default behavior of using the `%f` notation.
But, as I said before, these are the DEFAULT behavior and we can change these behaviors via `modifiers`.
Basically, modifiers, as the name suggests, they are used to modify the default behavior of a format specifier.
Let’s say in the example above, we want to only see 2 digits of the decimal part of a float value on the screen. Well, using the modifiers, we can easily do that.
Example: using modifiers in C format specifiers
#include <stdio.h> int main() { float height = 5.8; printf("The height is: %.2f", height); return 0; }
Output:
The height is: 5.80
In the example above, with the help of a modifier that is used between the `%f` notation, we could shrink down the decimal portion of the printed value to only 2 digits.
The modifier here for `%f` notation was a dot followed by a number as `.2` and this modifier appeared between `%` and the notation `f` in this example. The modifier in this example is telling the compiler that we only want to see two digits of the decimal part of the target value on the output stream.
Note: modifiers always appear between `%` and the target notation! For example, `f`.
List of Modifiers in C:
Here’s the list of modifiers:
Modifier | Meaning |
Flag | The five flags (-, +, space, #, and 0) are described in the table below |
Digit(s) | The minimum field with. A wider field will be used if the printed number or string won’t fit in the field. |
.digit(s) | Precision. For %e, %E, and %f conversions, the number of digits to be printed to the right of the decimal. For %g and %G conversions, the maximum number of significant digits. For %s conversions, the maximum number of characters to be printed. For integer conversions, the minimum number of digits to appear; leading zeros are used if necessary to meet this minimum. Using only `.` implies a following zero, so %.f is the same as %.0f |
h | Used with an integer conversion specifier to indicate a short int or unsigned short int value. |
hh | Used with an integer conversion specifier to indicate a signed char or unsigned char value. |
j | Used with an integer conversion specifier to indicate an intmax_t or uintmax_t value; these are types defined in stdint.h |
l | Used with an integer conversion specifier to indicate a long int or unsigned long int. |
ll | Used with an integer conversion specifier to indicate a long long int or unsigned long long int. |
L | Using with a floating-point conversion specifier to indicate a long double value. |
t | Used with an integer conversion specifier to indicate a ptrdiff_t value. This is the type curresponding to the difference between two pointers. (C99) |
z | Used with an integer conversion specifier to indicae a size_t. This is the type returned by sizeof. (C99) |
The table above is taken from the C Primer Plus, 6th Edition Book
Note: There’s no conversion-specifier for the `float` type though, this is because this type will be automatically converted into `double` before being used on the output stream, for example.
Example: using modifiers in C
#include <stdio.h> int main() { int i = 20; printf("%6d", i); printf("Hello\n"); printf("%-6d", i); printf("Hello"); return 0; }
Output:
20Hello 20 Hello
C Format Specifiers and Flags
Now let’s see the 5 flags that can be used as the modifier for conversion-specifications:
Flag | Meaning |
+ | Signed values are displayed with a plus sign, if positive, and with a minus sign, if negative. |
Space | Signed values are displayed with a leading space (but no sign) if positive and with a minus if negative. A + flag overrides a space |
– | The item is left-justified; that is, it is printed beginning at the left of the field |
# | Use an alternative form for the conversion specification. Produces an initial 0 for the %o form and an initial 0x or 0X for the %x or %X form, respectively. For all floating-point forms, # guarantees that a decimal-point character is printed, even if no digits follow. For %g and %G forms, it prevents trailing zeros from being removed |
0 | For numeric forms, pad the field width and leading zeros instead of with spaces. This flag is ignored if a – flag is present or if, for an integer form, a precision is specified. |
The table above is taken from the C Primer Plus, 6th Edition Book
Example:
#include <stdio.h> int main() { int i = 20; printf("%06d", i); printf("Hello"); return 0; }
Output:
000020Hello
Another example:
#include <stdio.h> int main() { char characterString[] = "Pure imagination"; printf("[%30.10s]\n", characterString); printf("[%10.5s]\n", characterString); printf("[%-10.5s]", characterString); return 0; }
Output:
[ Pure imagi] [ Pure ] [Pure ]
Before moving to the rest of this section, you should know about what is happening behind the scene when we call Format-specifiers:
The data in the memory is nothing but 0s and 1s.
When we use the conversion-specifiers, we’re basically telling that the value stored in the memory should be translated to a specific type.
For example, let’s say we have `int val = 75` variable.
This value is stored in the memory like this: 1001011
Now if we use the `%d` notation, this binary data in the memory will be translated into integer data-type and gets displayed on the screen.
At the same time, we could use `%c` to translate this binary form into its character representation!
Example: C and format specifiers
#include <stdio.h> int main() { int val = 75; printf("The integer representation is: %d\n", val); printf("The character representation is: %c\n",val); return 0; }
Output:
The integer representation is: 75 The character representation is: K
As you can see via `%d` and `%c` notations, we could get two different representation of the value assigned to the `val` variable.
Example: printf() for double in C
#include <stdio.h> int main() { double dVar = 23.43; printf("The value of the dVar variable is: %.3f",dVar); return 0; }
Output:
The value of the dVar variable is: 23.430
Example: the return value of the printf function in C
#include <stdio.h> int main() { int val = 75; int count = printf("The value is: %d\n", val); printf("%d",count); return 0; }
Output:
The value is: 75 17
In this example, the number of characters that is displayed on the screen is 17 and that’s what the `printf` function returned as well.