21

The printf() documentation says that if someone wants to print % in C, he can use:

printf("%%")

Why is it not:

printf("\%")

as with other special characters?

syb0rg
  • 8,057
  • 9
  • 41
  • 81
acgtyrant
  • 1,721
  • 1
  • 16
  • 24
  • 1
    Check out this link for more information; http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.cmds/doc/aixcmds4/printf.htm – JNL Jul 23 '13 at 13:33
  • 1
    This is just the way of printf. I'd rather use this reference http://www.cplusplus.com/reference/cstdio/printf/ – GreenScape Jul 23 '13 at 13:34

4 Answers4

38

The backslash is processed by the compiler when interpreting the source text of the program. So the common result is that the source text "\%" produces a string containing ”%”.

The format string is interpreted by the printf routine, so it processes the characters passed to it. By this time, the backslash is no longer present, so printf never sees it.

Technically, \% is not legal in a string literal. The character \ starts an escape sequence, and the only legal escape sequences are listed in C 2011 6.4.4.4 1. They are \ followed by ', ", ?, \, a, b, f, n, r, t, v, one to three octal digits, x and hexadecimal digits, u and four hexadecimal digits, or U and eight hexadecimal digits.

If printf had been designed so that a backslash would escape a percent, then you would have to pass it a backslash by escaping the backslash in the source text, so you would have to write:

printf("\\%");
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • 1
    +1 for the careful wording of "x and hexadecimal digits" http://stackoverflow.com/questions/5784969/when-did-c-compilers-start-considering-more-than-two-hex-digits-in-string-lite – chux - Reinstate Monica Aug 25 '13 at 14:36
30

Because the % is handled by printf. It is not a special character in C, but printf itself treats it differently.

Kninnug
  • 7,992
  • 1
  • 30
  • 42
4

The convention is that special characters escape themselves. So, rather than using backslash to escape the percent, it escapes itself. (Note that to pass a backslash to printf, you'd have to write the string literal as "\\%".)

Nicholas Wilson
  • 9,435
  • 1
  • 41
  • 80
  • The convention used with `\` by the compiler and `%` by printf is that those characters escape themselves. The convention within string literals and character is that backslash is used to escape the ending delimiters. Personally, I am of the belief that it's best to have the escaped representation of an escape character be that character followed by a particular *something else*; and avoid having escapes that look like other things, but the idea of doubling escape characters and preceding things like quotes with escapes (rather than using e.g. `\q` as an escaped quote) seems pretty common. – supercat Jun 10 '15 at 13:32
  • In string and character literals this applies too, backslash is the metacharacter and it escapes itself; quotation characters don't escape themselves in most languages, instead backslash is used for that. I think you're agreeing with me? There are some oddball schemes where doubled quotation marks are used to represent literal quotation marks (UTR35 springs to mind as an example of that, and it's a real nightmare). – Nicholas Wilson Jun 10 '15 at 14:10
  • Doubling metacharacters to represent themselves is a common pattern, though I don't know any real advantage to it besides popularity, since it means that one can't know what a particular character means without being able to see an arbitrary number of characters before it. Having the escaped representation for `\` be `\!` would avoid ambiguity about what a string that seems to end with `\\\\\\\\"` means [is the quote an escaped part of the string or not?] Other languages use some different approaches, though sometimes they generate ambiguities of their own (E.g. .NET format strings). – supercat Jun 10 '15 at 15:13
0

You can do it !!!!!

#include <iostream>
#include <string>
#include "stdio.h"
using namespace std;



int main(int argc, char **argv)
{


    printf("hhhhhhh %s \n","\%");
    printf("hhhhhhh  \n");

    return 0;
}

The problem exist with printf and differ from the compiler you use .. With wxWidget lib you can not use printf with two escape sequences

printf(" xxxxxx  \0x81  xx \0x82 xx \n");

don t go. But if you use

printf(" xxxxxx  %s  xx %s \n","\0x81","\0x82"); 

you are right. A plus