Reading a string with scanf

abeln picture abeln · Mar 23, 2011 · Viewed 567.1k times · Source

I'm a little bit confused about something. I was under the impression that the correct way of reading a C string with scanf() went along the lines of

(never mind the possible buffer overflow, it's just a simple example)

char string[256];
scanf( "%s" , string );

However, the following seems to work too,

scanf( "%s" , &string );

Is this just my compiler (gcc), pure luck, or something else?

Answer

Gareth McCaughan picture Gareth McCaughan · Mar 23, 2011

An array "decays" into a pointer to its first element, so scanf("%s", string) is equivalent to scanf("%s", &string[0]). On the other hand, scanf("%s", &string) passes a pointer-to-char[256], but it points to the same place.

Then scanf, when processing the tail of its argument list, will try to pull out a char *. That's the Right Thing when you've passed in string or &string[0], but when you've passed in &string you're depending on something that the language standard doesn't guarantee, namely that the pointers &string and &string[0] -- pointers to objects of different types and sizes that start at the same place -- are represented the same way.

I don't believe I've ever encountered a system on which that doesn't work, and in practice you're probably safe. None the less, it's wrong, and it could fail on some platforms. (Hypothetical example: a "debugging" implementation that includes type information with every pointer. I think the C implementation on the Symbolics "Lisp Machines" did something like this.)