335

How do you escape the % sign when using printf in C?

printf("hello\%"); /* not like this */
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chris_45
  • 8,769
  • 16
  • 62
  • 73
  • 1
    `"hello\%"` doesn't work because it produces the string `hello%` plus NUL just like `"hello%"` does. – ikegami Feb 17 '21 at 05:53
  • 1
    `"hello\%"` doesn't work because... for me... it does not compile. I used Microsoft Visual Studio 2017. The compilation fails with the message: `'%': unrecognized character escape sequence.` – Djibril NDIAYE Apr 12 '21 at 16:46
  • @DjibrilNDIAYE It appears [clang and gcc had their reasons](https://stackoverflow.com/questions/34142682/what-is-the-backslash-percent-escape-in-c) to go against the standard and allow `\%`. – Ruud Helderman Sep 15 '22 at 13:10

13 Answers13

510

You can escape it by posting a double '%' like this: %%

Using your example:

printf("hello%%");

Escaping the '%' sign is only for printf. If you do:

char a[5];
strcpy(a, "%%");
printf("This is a's value: %s\n", a);

It will print: This is a's value: %%

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Pablo Santa Cruz
  • 176,835
  • 32
  • 241
  • 292
  • 9
    "printf("hello%%");" is right. But it's not a escape I think. use printf("hello\045"); – Lai Jiangshan Dec 11 '09 at 03:12
  • 1
    @Pablo Santa Cruz: this method to "escape" `%` is specific to `printf`, correct? – Lazer Mar 27 '10 at 12:20
  • for formatted functions (afaik they ends all with an `f`) in general, indeed! – ShinTakezou Jul 01 '10 at 08:26
  • 10
    This is a special case of the very common rule in escaping systems that to get a literal escape symbol you use . – dmckee --- ex-moderator kitten Jul 01 '10 at 14:49
  • 12
    Lai Jiangshan, this won't work. `\045` is compile-time escape that is part of the **language** and will turn into `%` when compiled. `printf` is a run-time function, so it deals with bytes of your string, not with C source code, and it has its own escape sequences that are parts of the **function**. In short, `printf` is a "language inside a language", and `printf("This is a's value: %s\n", a);` gives the same result as `printf("This is a's value: \045\0163\012", a);`. – Triang3l May 07 '13 at 14:23
  • `char a[5];` is too much, `char a[3];` would be enough. On little-endian systems, you can even use `*((long *)a) = '%%';` instead of `strcpy`, and on big-endian systems, `*((long *)a) = '%%\0\0';`. – Triang3l May 07 '13 at 14:26
  • 6
    Also, you can do this: `printf("hello%c", '%');`. However, `%%` is better because it doesn't use another argument. – Triang3l May 07 '13 at 14:28
  • Works also for `__android_log_print` – Antonio Nov 30 '16 at 09:04
  • Some embedded builds of `libc` do not seem to include support for escaping the percent sign. – sherrellbc Feb 28 '17 at 23:50
  • @Triang3l, or just use `const char *a="%%"`. A other way is `uint64_t s=0x0025256F6C6C6568ULL;` `printf((const char *)&s);`(will print `hello%`). But better do not use this method. – 12431234123412341234123 Apr 13 '17 at 12:40
43

As others have said, %% will escape the %.

Note, however, that you should never do this:

char c[100];
char *c2;
...
printf(c); /* OR */
printf(c2);

Whenever you have to print a string, always, always, always print it using

printf("%s", c)

to prevent an embedded % from causing problems (memory violations, segmentation faults, etc.).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mikeage
  • 6,424
  • 4
  • 36
  • 54
  • The warning is generally appropriate however there may be situations in which you want to do "this" - as long as you know that the string you provide will be interpreted as a format string. – PP. Dec 07 '09 at 14:17
  • 4
    I came up with an alternate solution once - copy the buffer to another buffer and then go through it doubling up the % signs. I eventually came across this idea and replaced a 20-30 line function with one line. Don't worry, I did beat myself severely about the head, as I deserved. – Graeme Perrow Dec 07 '09 at 14:19
  • True, but don't forget that 99% of the time when you get a format string, you get the arguments as a va_list, so you need to use vprintf. Thus, I'm technically correct ;) – Mikeage Dec 07 '09 at 14:20
  • 2
    It's so much easier to do puts( c ). If – William Pursell Dec 07 '09 at 14:48
  • 1
    puts appends a newline. That's often unwanted behavior. – Mikeage Dec 08 '09 at 10:51
  • 1
    @Mikeage: If unwanted, do `fputs(string, stdout);` or `printf("%s", string);` – Jonas Kölker Nov 02 '15 at 15:00
  • But .Format(L"%s", ) would absolutely cause my program crash. I'm still using .Format(L"%c", ) though it would crash sometimes. – Moses May 26 '16 at 05:23
36

If there are no formats in the string, you can use puts (or fputs):

puts("hello%");

if there is a format in the string:

printf("%.2f%%", 53.2);

As noted in the comments, puts appends a \n to the output and fputs does not.

Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
  • 6
    Worth mentioning fputs() also, as it directly reciprocates to fprintf(). – Tim Post Dec 08 '09 at 05:55
  • 1
    puts also appends a newline [even if you already have one]. If you want that, great. Otherwise... – Mikeage Dec 08 '09 at 10:51
  • @Sinan Ünür: thanks for reminding me about `puts`. I never thought of `puts` for printing strings and jumped straight to `printf`. Not anymore. – Lazer Mar 24 '10 at 17:03
12

With itself...

printf("hello%%"); /* like this */
martin clayton
  • 76,436
  • 32
  • 213
  • 198
8

Use a double %%:

printf("hello%%");
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
jldupont
  • 93,734
  • 56
  • 203
  • 318
7

Nitpick:
You don't really escape the % in the string that specifies the format for the printf() (and scanf()) family of functions.

The %, in the printf() (and scanf()) family of functions, starts a conversion specification. One of the rules for conversion specification states that a % as a conversion specifier (immediately following the % that started the conversion specification) causes a '%' character to be written with no argument converted.

The string really has 2 '%' characters inside (as opposed to escaping characters: "a\bc" is a string with 3 non null characters; "a%%b" is a string with 4 non null characters).

pmg
  • 106,608
  • 13
  • 126
  • 198
  • 2
    techinically, it is still "escaping"; characters that are special need a way to "escape" their special meaning and be back to their "character nature" – ShinTakezou Jul 01 '10 at 08:29
6

Like this:

printf("hello%%");
//-----------^^ inside printf, use two percent signs together
Salman A
  • 262,204
  • 82
  • 430
  • 521
6

You can use %%:

printf("100%%");

The result is:

100%

Donald Duck
  • 8,409
  • 22
  • 75
  • 99
5

You are using the incorrect format specifier. You should use %% for printing %. Your code should be:

printf("hello%%");  

Read more all format specifiers used in C.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Pankaj Prakash
  • 2,300
  • 30
  • 31
4

The backslash in C is used to escape characters in strings. Strings would not recognize % as a special character, and therefore no escape would be necessary. printf is another matter: use %% to print one %.

Donald Duck
  • 8,409
  • 22
  • 75
  • 99
Ralph M. Rickenbach
  • 12,893
  • 5
  • 29
  • 49
3

Yup, use printf("hello%%"); and it's done.

Donald Duck
  • 8,409
  • 22
  • 75
  • 99
Kevin
  • 41
  • 4
3

You can simply use % twice, that is "%%"

Example:

printf("You gave me 12.3 %% of profit");
Lahiru Jayaratne
  • 1,684
  • 4
  • 31
  • 35
Md Shahriar
  • 2,072
  • 22
  • 11
2

The double '%' works also in ".Format(…). Example (with iDrawApertureMask == 87, fCornerRadMask == 0.05): csCurrentLine.Format("\%ADD%2d%C,%6.4f*\%",iDrawApertureMask,fCornerRadMask) ; gives the desired and expected value of (string contents in) csCurrentLine; "%ADD87C, 0.0500*%"

dindea
  • 21
  • 2