What will be the output, if we print a string that contains "%s" in it?

As specified in other answered, a undefined behavior will occur.

What the undefined behavior means in this context: When printf receives a string with n number of format specifiers (such as %s) it is going to expect n number of parameters to be passed to the function in addition to the string. So, when you have a statement like this printf("hi%s"), the function will behave as if you passed a parameter (in this case the second parameter should be a char *) even though there is not. The function is just going to get the next value on the stack which is some junk value in this case. Then the function will deference this junk value and will treat it as a buffer of characters. The reasons why this behavour is undefined is there is no telling what the junk value on the stack could be.

Possible Outcomes

  1. The junk value on the stack is 0 -> Segmentation fault when junk value is dereferenced.

  2. The junk value on the stack happens to be a valid memory address -> The bytes at the memory location will keep getting inserted into the string (appended to "hi" in this case) until either a byte of value 0 is encountered or a segmentation fault occurs.

  3. The junk value on the stack is not 0 but is not a valid memory location -> Segmentation fault when junk value is dereferenced.

Producing the same situation The below portion of code is a very similar situation to printf("hi%s")

void foo() {
   char * myJunkValue;  // Since not a global/static variable, this is not guaranteed to be 0
   printf(myJunkValue); // Undefined behavior
}

Your program invokes undefined behaviour.

Your code is equivalent to

 printf("hi%s");

where %s is a conversion specifier and it expects an argument to be supplied.

Quoting C11, chapter §7.21.6.1

[...] If there are insufficient arguments for the format, the behavior is undefined. [....]

Suggestion: If you just have to print a string, without a need of any conversion (formatting), you can use puts().


You're not "printing a string which has %s in its content". You're passing such a string as the format string to printf, and by doing so without a matching argument for the format field, your program has undefined behavior. The first argument to printf is not a string you want to print. It's a format string that controls how the remaining arguments are interpreted/converted, and which can also contain literal text to merge them into.

"Printing a string which has %s in its content" (where ptr points to that string, as in your question) can be accomplished by printf("%s", ptr) or puts(ptr).