tags:

views:

328

answers:

5

When I compile scanf("%s", &var);, gcc sends back a warning:

warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[20]’

however when I compile scanf("%s", var);, no warning is applied. Both pieces of code work and the book I am reading specifically says to use the ampersand, but even it doesn't in some of the examples.

My question is, should I continue to use the ampersand, even when the book doesn't specify?

+2  A: 

From what you've posted var is a char array. In that case, you don't need the ampersand, just the name var will evaluate to a (char *) as needed.

Details:

scanf needs a pointer to the variable that will store input. In the case of a string, you need a pointer to an array of characters in memory big enough to store whatever string is read in. When you declare something like char var[100], you make space for 100 chars with var[0] referring to the first char and var[99] referring to the 100th char. The array name by itself evaluates to exactly the same thing as &var[0], which is a pointer to the first character of the sequence, exactly what is needed by scanf. So all you need to do is scanf("%s", var);, but be aware that scanf does not enforce size constraints on input strings, so if the user inputs a 101 length string your will have a buffer overrun, which will result in bugs or, even worse, security problems. The better choice is generally fgets which does allow size constraints for input strings.

Graphics Noob
A: 

char arrays are already char * so you do not need the ampersand.

fanar
+1  A: 

I invite any other answerers to give a good summary of pointers and references here. I don't think I can do that without making some mistakes here and there, and I have no intent to deal with the nerd rage that will follow.

So I'll just point you to a good resource to learn about pointers and references which lies at the heart of your problem. http://www.cplusplus.com/doc/tutorial/pointers/

NomeN
+1 for typical SO nerd rage... sometimes it seems like there is a contest somewhere to see who can post the most "BUT! BUT! UNDEFINED BEHAVIOR OMG" comments in one day.
SoapBox
A: 

When you use an array like this one:

char name[20];

you must consider that a memory area composed by 20 chars is associated with it. To obtain the address of the beginning of that memory area you must use the name of the array, while to obtain the address of a single char of that array, you have to use a sintax like this: &name[i].
You are using scanf to read a string, which is an array of char in C. scanf require the address of the memory area associated to the type of variable to read. In this case, you are reading an array so you have only to use the name. If you want to read a single variable and not an array you have to use the ampersand. For example:

char myChar;
scanf("%c", &myChar);

I hope this can be helpful.

Maurizio Reginelli
A: 

@Graphics Noob: it's possible to specify the length using scanf. scanf("%10s", var);

Leandro
then say so in a comment... like this one
NomeN