¿Por qué recibo advertencias sobre este ejemplo de código? ¿Qué es correcto?

Estoy aprendiendo algo de C, y estaba leyendo sobre scanf en este tutorial donde se incluye el siguiente bloque de código:

 #include  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); } 

Sin embargo recibo advertencias de que:

 "Format specifies type 'char *' but the argument has type 'char (*)[20]' 

¿Está mal el tutorial?

Esto debería funcionar para usted:

 #include  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); } 

Hay un error en el ejemplo del tutorial.

Cambio:

 scanf("%s", &str1); 

a

 scanf("%s", str1); 

s especificador de conversión s requiere un puntero a char pero está pasando un puntero a una matriz.

Las líneas

 scanf("%s", &str1); 

y

 scanf("%s", &str2); 

de hecho están equivocados (al menos, ambos contienen un error tipográfico). Deben escribirse como

 scanf("%s", str1); // no & operator 

y

 scanf("%s", str2); // ditto 

Las matrices y expresiones de matrices son especiales en C. Excepto cuando es el operando de sizeof o unary & operator, o si se utiliza un literal de cadena para inicializar otra matriz en una statement, una expresión de tipo “matriz de elementos N de T ” se convertirá (decaer) en una expresión de tipo “puntero a T “, y el valor de la expresión será la dirección del primer elemento de la matriz.

La expresión str1 tiene el tipo “matriz de 20 elementos de char “. Si str1 aparece en un contexto donde no es el operando de sizeof o unary & operator, se convertirá en una expresión de tipo “puntero a char “, y el valor de la expresión será el mismo que &str1[0] ; esta es la razón por la que no necesita usar las cadenas & para leer, ya que la expresión de matriz se tratará como un puntero. Sin embargo, cuando es el operando del operador unario & , la regla de conversión no se aplica, y el tipo de expresión &str1 es “puntero a la matriz de 20 elementos de char ” ( char (*)[20] ). De ahí su advertencia.

El valor de str1 y &str1 será el mismo (la dirección de la primera matriz de elementos es la misma que la de la matriz), pero los tipos de las expresiones son diferentes, y el tipo importa. Un puntero a char se tratará de forma diferente de un puntero a una matriz de char .

El 90% de los libros y tutoriales de C son basura ; ser muy escéptico con cualquier referencia de C que no sea el estándar real. Harbison & Steele’s C: A Reference Manual (actualmente, 5ª edición) ha sido mi referencia de referencia desde finales de los 80, pero incluso tiene pequeños errores.