Variable argument lists -- like used for printf()
or scanf()
-- cannot check their variable arguments for type-correctness. To the contrary, these functions rely on the format string stating the correct type, because the format string defines the number and type of arguments pulled from the stack.
(Check the documentation for <stdargs.h>
for details on how variable argument lists work.)
If you state "%s"
as format specifier, scanf()
will pull a char *
from the stack and write the standard input to that address, no matter what you actually gave as a parameter, or whether you gave a parameter at all.
Needless to say, if your format specifiers don't match your arguments in number, type and order, you might be lucky and actually get a result, but you're definitely invoking undefined behaviour.
(This is talking about the general "why doesn't this give me an error" question, assuming that you don't have a modern compiler and the appropriate warning enabled, like -Wformat
for GCC. As for the type conversions in your specific case, see Daniel's answer.)
PS: While we are at it, using scanf()
in combination with %s
is pretty lethal in any case, because a too-long input would clobber your program. At least limit the input, e.g. via %10s
. Better yet, read the input via fgets()
and do proper input parsing in memory, since scanf()
's abilities to recover gracefully from malformed input are severely limited.