Print the percentage character with printf() in C
By Flavio Copes
Learn how to print the percentage character with printf() in C, where a single % gives an incomplete format specifier warning, so write %% instead.
To print the % character with printf() in C, write %% in the format string. A single % doesn’t work, because printf() treats it as the start of a format specifier.
You’ll hit this early. Perhaps you are working on a program that calculates percentages, which is common when you’re learning the language and writing small programs.
Why a single % fails
The first argument of printf() is a format string. Inside it, % has a special meaning: it starts a conversion specifier, like %d for integers or %s for strings.
So when the compiler sees a % followed by nothing useful, the specifier is incomplete. If you try this:
printf("%");
it will not work, and the compiler gives you a warning like:
hello.c:9:14: warning: incomplete format specifier
[-Wformat]
printf("%");
^
1 warning generated.
and the character is not printed. The behavior of a malformed format string is undefined in C, so don’t ignore this warning.
The fix
Write %%. The two characters together are the conversion specifier that means “print a literal percent sign”:
printf("%%");
In a real program you’ll combine it with a value. This prints an integer followed by the percent sign:
int battery = 78;
printf("Battery at %d%%\n", battery);
//Battery at 78%
Read it as three parts: %d prints the number, %% prints the sign, \n ends the line.
When you don’t need the escape
The %% rule only applies to format strings. Functions that don’t parse formats take the character as-is:
puts("Loading: 100%");
putchar('%');
Both print the % with no escaping, because there’s no format parsing involved.
A related pitfall
This same mechanism is why you should never pass external text directly as the format string:
printf(message);
If message happens to contain a %, printf() interprets it as a specifier and reads arguments you never passed. Best case garbage output, worst case a crash or a security hole.
The fix is to always print variable text through %s:
printf("%s", message);
Now the % characters inside message are just data, and they print correctly.