Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does C's printf format string have both %c and %s?

People also ask

What does %c mean in printf?

%s is for string %d is for decimal (or int) %c is for character.

What is the difference between %C and %S?

"%s" expects a pointer to a null-terminated string ( char* ). "%c" expects a character ( int ).

What is the purpose of %c format specifier?

The %c format specifier is implemented for representing characters. It is used with the printf() function for printing the character stored in a variable. You should incorporate the %c format specifier when you want to print character data.

What does %C do in C?

%d is used to print decimal(integer) number ,while %c is used to print character . If you try to print a character with %d format the computer will print the ASCII code of the character.


Probably to distinguish between null terminated string and a character. If they just had %s, then every single character must also be null terminated.

char c = 'a';

In the above case, c must be null terminated. This is my assumption though :)


%s prints out chars until it reaches a 0 (or '\0', same thing).

If you just have a char x;, printing it with printf("%s", &x); - you'd have to provide the address, since %s expects a char* - would yield unexpected results, as &x + 1 might not be 0.

So you couldn't just print a single character unless it was null-terminated (very inefficent).

EDIT: As other have pointed out, the two expect different things in the var args parameters - one a pointer, the other a single char. But that difference is somewhat clear.


The issue that is mentioned by others that a single character would have to be null terminated isn't a real one. This could be dealt with by providing a precision to the format %.1s would do the trick.

What is more important in my view is that for %s in any of its forms you'd have to provide a pointer to one or several characters. That would mean that you wouldn't be able to print rvalues (computed expressions, function returns etc) or register variables.

Edit: I am really pissed off by the reaction to this answer, so I will probably delete this, this is really not worth it. It seems that people react on this without even having read the question or knowing how to appreciate the technicality of the question.

To make that clear: I don't say that you should prefer %.1s over %c. I only say that reasons why %c cannot be replaced by that are different than the other answer pretend to tell. These other answers are just technically wrong. Null termination is not an issue with %s.


The printf function is a variadic function, meaning that it has variable number of arguments. Arguments are pushed on the stack before the function (printf) is called. In order for the function printf to use the stack, it needs to know information about what is in the stack, the format string is used for that purpose.

e.g.

printf( "%c", ch );    tells the function the argument 'ch' 
                       is to be interpreted as a character and sizeof(char)

whereas

printf( "%s", s );   tells the function the argument 's' is a pointer 
                     to a null terminated string sizeof(char*)

it is not possible inside the printf function to otherwise determine stack contents e.g. distinguishing between 'ch' and 's' because in C there is no type checking during runtime.


%s says print all the characters until you find a null (treat the variable as a pointer).

%c says print just one character (treat the variable as a character code)

Using %s for a character doesn't work because the character is going to be treated like a pointer, then it's going to try to print all the characters following that place in memory until it finds a null

Stealing from the other answers to explain it in a different way.

If you wanted to print a character using %s, you could use the following to properly pass it an address of a char and to keep it from writing garbage on the screen until finding a null.

char c = 'c';
printf('%.1s', &c);

For %s, we need provide the address of string, not its value.

For %c, we provide the value of characters.

If we used the %s instead of %c, how would we provide a '\0' after the characters?


Id like to add another point of perspective to this fun question.

Really this comes down to data typing. I have seen answers on here that state that you could provide a pointer to the char, and provide a

"%.1s"

This could indeed be true. But the answer lies in the C designer's trying to provide flexibility to the programmer, and indeed a (albeit small) way of decreasing footprint of your application.

Sometimes a programmer might like to run a series of if-else statements or a switch-case, where the need is to simply output a character based upon the state. For this, hard coding the the characters could indeed take less actual space in memory as the single characters are 8 bits versus the pointer which is 32 or 64 bits (for 64 bit computers). A pointer will take up more space in memory.

If you would like to decrease the size through using actual chars versus pointers to chars, then there are two ways one could think to do this within printf types of operators. One would be to key off of the .1s, but how is the routine supposed to know for certain that you are truly providing a char type versus a pointer to a char or pointer to a string (array of chars)? This is why they went with the "%c", as it is different.

Fun Question :-)