0

Why do I need an ampersand before the array in the printf statement here, but any other time ampersand is only used in scanf?

Completely new so if you could explain as simply as possible that would help.


int main(void) {

  char word[1];
  scanf("%s", &word[0]);
  printf("%s", word[0]);
  return 0;
}
Blaze
  • 16,736
  • 2
  • 25
  • 44
  • 1
    Possible duplicate of [Why doesn't scanf need an ampersand for strings and also works fine in printf (in C)?](https://stackoverflow.com/questions/1931850/why-doesnt-scanf-need-an-ampersand-for-strings-and-also-works-fine-in-printf-i) – phuclv May 10 '19 at 08:27

3 Answers3

3

You do need one. It's incorrect without one and leads to undefined behavior, which may cause anything to happen (even the program appearing to work correctly). Also, word[1] can only hold the null terminator of an empty string, any more than that and it will cause the buffer to overflow, also causing undefined behavior. It should be:

int main(void) {
    char word[10]; // or any value that is big enough for the input that your anticipating
    scanf("%9s", &word[0]);
    printf("%s", &word[0]);
    return 0;
}

And of course you can replace &word[0] with word.

Also note that I put %9s instead of just %s for the scanf call, which means that it will get at most 9 characters, which with the added null terminator fits into the word[10] that we have as an example. This way you don't get undefined behavior if the user enters something that's too big and instead it would just truncate that input.

Blaze
  • 16,736
  • 2
  • 25
  • 44
0

word[0] is the first character. the & sign is used to get a pointer to such character.

Claudio
  • 10,614
  • 4
  • 31
  • 71
0
scanf("%s", &word[0]);
printf("%s", word[0]);

In C, a string (addressed by %s in above statements) is defined as an array. Your declaration of "word":

char word[1];

declares an array, so that array can be a string (I wrote can, because it's a very short string...). If you use the identifier alone, "word", the compiler uses a pointer to the first element of the array. Hence:

scanf("%s", word);
printf("%s", word);

are both correct. But if you use an index into the array, like "word[0]", then you are no more using the array per se, but instead an element of it. This notation does not generate a pointer, but your above statements do need a pointer. So you can use an "&" to get a pointer.

Conclusion: if you have a string, use its simple name without indexing inside the array. Using the ampersand makes it clear that we pass a reference, but "&word[0]" is ugly and, moreover, everybody should know that scanf() writes into its arguments.