Print the percentage character with printf() in C

By

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.

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.

Tagged: C · All topics
~~~

Related posts about clang: