Reputation: 1025
I am trying to run a simple C program, but I am getting this error:
warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[20]’
I am running Mac OS X v10.8 (Mountain Lion) and am compiling in the terminal using GCC 4.2.1.
#include <stdio.h>
int main() {
char me[20];
printf("What is your name?");
scanf("%s", &me);
printf("Darn glad to meet you, %s!\n", me);
return (0);
}
Upvotes: 29
Views: 114197
Reputation: 43528
scanf("%s", &me);
should be
scanf("%s", me);
Explanation:
"%s"
means that scanf
is expecting a pointer to the first element of a char
array.
me
is an array object. Array objects are said to decay as a pointer to their first element when passed to a function or used in most expressions except as an argument to sizeof
and _Alignof
. So passing me
or &me[0]
is equivalent and the preferred way is to simply pass the destination as me
.
Adding &
to me
creates a pointer to arrays of 20 chars, with type char (*)[20]
, which is different from the type scanf
expects for %s
. The compiler reports the type mismatch but the program probably behaves as you expect because both &me[0]
and &me
refer to the same memory location so scanf()
really receives the correct address, albeit with an incorrect type.
Code critic:
Using "%s"
could cause a buffer overflow if the user inputs a word longer than 19 bytes, so tell scanf()
to limit the input to 19 bytes by specifying "%19s"
:
scanf("%19s", me);
Note also that the return value of scanf()
is the number of successful conversions, so 1
if input was processed successfully for %s
, and 0
or EOF
otherwise. It is always best to test for scanf()
failure to read all inputs and only use the destination variables in case of success:
#include <stdio.h>
int main(void) {
char me[20];
printf("What is your name?");
if (scanf("%19s", me) == 1)
printf("Darn glad to meet you, %s!\n", me);
else
printf("Sorry you had to leave!\n");
return 0;
}
Upvotes: 55
Reputation: 121
Another way you could fix this issue is by doing this:
scanf("%s",&me[0]);
You actually have to give the array's starting point (which in most languages is 0).
Upvotes: 3
Reputation: 123488
Except when it is the operand of the sizeof
, _Alignof
, or unary &
operators, or is a string literal being used to initialize an array in a declaration, an expression of type "N-element array of T
" will be converted ("decay") to an expression of type "pointer to T
", and it will evaluate to the address of the first element in the array.
The array me
is declared as a 20-element array of char
; normally, when the expression me
appears in your code, it will be treated as an expression of type "pointer to char
". If you had written
scanf("%s", me);
then you wouldn't have gotten the error; the expression me
would have been converted to an expression of the correct type.
By using the &
operator, however, you've bypassed that rule; instead of a pointer to char
, you're passing a pointer to an array of char
(char (*)[20]
), which is not what scanf
expects for the %s
conversion specifier, hence the diagnostic.
Upvotes: 4