San
San

Reputation: 169

What happens when a format specifier is not given to printf?

I came across this question in careercup about printf.

char *str = "hello";
printf("%s",str);
printf(str);

Second printf statement sometimes crash. I checked on various sites. Wrote the program to see if it actually does. But it does not. Also, I know that printf accepts an argument of type "const char* format" but format can be any constant string like "hello". But if I store it in a string str (which is ofcourse pointing to read-only memory). It is expected to work the same way. What exactly happens?

Can someone give a thorough explanation.

Upvotes: 1

Views: 1565

Answers (3)

LihO
LihO

Reputation: 42133

char *str = "hello";
printf(str);

is equivalent to:

printf("hello");

Just like:

char *format = "%s",
     *str = "hello";
printf(format, str);

is equivalent to:

char *str = "hello";
printf("%s",str);

... and whether you can truly rely on the content of format or not is completely different story.

Upvotes: 0

ouah
ouah

Reputation: 145919

Format specifiers in the format string are not required so:

printf("%s", "Hello world\n");

and

printf("Hello world\n");

will produce the same behavior.

However if the string in:

printf(str);

comes from an user input, you should use the %s specifier otherwise you are prone to format string attacks (the attacker could forge strings with %x to dump the stack and %n to overwrite memory).

Upvotes: 3

Kerrek SB
Kerrek SB

Reputation: 477640

It is generally not safe to call printf with a dynamic format string:

void foo(char const * p)
{
    printf(p);   // !
}

You cannot tell from the program source code alone whether the program is correct. The correctness depends on the value of the string (i.e. it must not contain format specifiers), and it may be undefined behaviour.

This is one of the unsafe aspects of the language: you are abandoning the type system (because of the variable arguments), and so you abandon static correctness verifiability.

The safe way to print a string literally would be either fputs(p, stdout), or (less efficiently perhaps) printf("%s", p).

Upvotes: 2

Related Questions