I'd like to know what the result would be if we print a string that contains "%s" in its content?
I tried printing it as "hi%s".
char *ptr="hi%s";
printf(ptr);
I expected the output to be as "hi". but i got it as "hi hi%s".
"hi hi%s"
I'd like to know what the result would be if we print a string that contains "%s" in its content?
I tried printing it as "hi%s".
char *ptr="hi%s";
printf(ptr);
I expected the output to be as "hi". but i got it as "hi hi%s".
"hi hi%s"
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
The junk value on the stack is 0 -> Segmentation fault when junk value is dereferenced.
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.
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()
.
puts()
appends a newline. –
Bowe fputs()
the best compromise? –
Expellee puts( s )
is not equivalent to printf( "%s", s )
, but fputs( s, stdout )
is. –
Bowe 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)
.
There will be undefined behavior.:)
This part of the string literal %s
is considered by the function as a format specifier.
From the C Standard (7.21.6.1 The fprintf function)
- ... If there are insufficient arguments for the format, the behavior is undefined.
If you want to output the string "hi%s"
as is you should define the literal like "hi%%s"
.
Here is a demonstrative program
#include <stdio.h>
int main(void)
{
char *ptr = "hi%%s";
printf( ptr );
return 0;
}
Its output is
hi%s
As other answered have mentioned, what you're doing invokes undefined behavior because you're calling printf
without enough arguments for the given format specifier. In your case you got junk output, but your program could have just as easily crashed.
To expand on this, code that looks like this:
printf(ptr);
Is almost always wrong. If the string that ptr
points to can be controlled by the user in any way, you open yourself up to a format string vulnerability. The user could supply a specially crafted string using %s
, %x
, etc. that could dump the contents of memory and expose sensitive data, or a string using %n
that could write to memory and allow an attacker to take over your program.
Many static analyzers will throw a warning if the first argument to printf
is not a string constant for this reason.
© 2022 - 2024 — McMap. All rights reserved.
printf
expects extra parameter passed for%s
– Nonesuchprintf("%s\n", ptr);
? – Holoblasticfwrite(ptr, 1, strlen(ptr), stdout)
orprintf("%s", ptr)
. – Sonometer