l00kitsjake
l00kitsjake

Reputation: 1025

Compiler message "warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)’"

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

Answers (3)

MOHAMED
MOHAMED

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

Ravi Arora
Ravi Arora

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

John Bode
John Bode

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

Related Questions