I'm learning some C, and was reading up on scanf
from this tutorial where the following code block is included:
#include <stdio.h>
int main()
{
char str1[20], str2[30];
printf("Enter name: ");
scanf("%s", &str1);
printf("Enter your website name: ");
scanf("%s", &str2);
printf("Entered Name: %s\n", str1);
printf("Entered Website:%s", str2);
return(0);
}
However I get warnings that:
"Format specifies type 'char *' but the argument has type 'char (*)[20]'
Is the tutorial wrong?
This should work for you:
#include <stdio.h>
int main()
{
char str1[20], str2[30];
printf("Enter name: ");
scanf("%19s", str1);
//^^ ^ Removed address operator
//So only the right amount of characters gets read
printf("Enter your website name: ");
scanf(" %29s", str2);
//^ Added space to catch line breaks from the buffer
printf("Entered Name: %s\n", str1);
printf("Entered Website:%s", str2);
return(0);
}
There is a bug in the example of the tutorial.
Change:
scanf("%s", &str1);
to
scanf("%s", str1);
s
conversion specifier requires a pointer to char
but you are passing a pointer to an array.
The lines
scanf("%s", &str1);
and
scanf("%s", &str2);
are indeed wrong (at the very least, they both contain a typo). They should be written as
scanf("%s", str1); // no & operator
and
scanf("%s", str2); // ditto
Arrays and array expressions are special in C. Except when it is the operand of the sizeof or unary &
operators, or is a string literal being used to initialize another 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 the value of the expression will be the address of the first element of the array.
The expression str1
has type "20-element array of char
". If str1
appears in a context where it's not the operand of the sizeof
or unary &
operators, it will be converted to an expression of type "pointer to char
", and the value of the expression will be the same as &str1[0]
; this is why you don't need to use the &
for reading strings, since the array expression will be treated as a pointer. However, when it's the operand of the unary &
operator, the conversion rule doesn't apply, and the type of the expression &str1
is "pointer to 20-element array of char
" (char (*)[20]
). Hence your warning.
The value of str1
and &str1
will be the same (the address of the first element array is the same as the address of the array), but the types of the expressions are different, and type matters. A pointer to char
will be treated differently from a pointer to array of char
.
90% of C books and tutorials are crap; be very skeptical of any C reference that isn't the actual standard. Harbison & Steele's C: A Reference Manual (currently 5th edition) has been my go-to reference since the late '80s, but even it has small errors.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With