scanf no imprime ni lee nada

Tengo la siguiente línea en mi código:

char y[] = "a"; scanf("Letter: %s", y); printf("%s\n", y); 

La segunda línea no afecta en absoluto a la salida de la tercera línea. He incluido , no puedo pensar en lo que está mal …

Uno de los errores más grandes que uno hace, es incluir cualquier cadena en la función scanf entre las comillas que no sean la especificación de formato (como %s o %d ). El código debe ser scanf("%s",y) . Si toma Cualquier otro personaje tendrá que rascarse la cabeza buscando problemas.

(Incluso si incluye cualquier carácter, debe ingresar ese carácter, por ejemplo, si escribe scanf("letter: %s",y); luego, en la entrada debe escribir como C:\>letter: “letra que ingresará “ ) que obviamente no es una buena idea. Además, la función scanf no está ahí para imprimir cosas, es solo para leer la entrada del terminal. Para imprimir, debe usar printf("letter"); Eso es.

Supongamos que tiene que tomar entradas de dos variables int usando un scanf() entonces usará como scanf("%d%d",&a,&b); Como puede ver, no he puesto nada excepto las especificaciones de formato en las comillas.

Supongo que querías un mensaje, no una cadena de formato:

 printf("Letter: "); fflush(stdout); scanf("%s", y); 

Solo ten en cuenta que tu cadena solo tendrá un carácter. Si ingresa una cadena más larga, tendrá una saturación del búfer.

También debe acostumbrarse a probar el valor de retorno de scanf . Devuelve el número de elementos leídos con éxito. Entonces, en su ejemplo, si lee una cadena, debería devolver 1 . Debido a que no lo probó, pasó mucho tiempo tratando de averiguar qué es lo que está mal, cuando en realidad le habría dicho que no se leyó ningún artículo.

Otras respuestas han diagnosticado correctamente que scanf() no genera ningún dato (y, en particular, no genera ningún mensaje), mientras que la pregunta parece esperar que scanf("Letter: %s", y) emitirá un mensaje. Letter: y luego leer una respuesta. También hay problemas, como no comprobar el valor de retorno de scanf() y un desbordamiento de búfer si se escribe más de un carácter.

Una de las respuestas sugirió que los caracteres distintos de las especificaciones de conversión no deberían estar presentes en la cadena de formato. Esta respuesta es principalmente un contraejemplo que muestra cómo otros personajes pueden ser cruciales. Puede tomar este código de ejemplo y realizar modificaciones para mejorar su comprensión de cómo funciona la familia de funciones scanf() . Tenga en cuenta que no es un progtwig interactivo; está convirtiendo datos usando sscanf() , casi como si fgets() hubiera leído los datos. Ejercicio: ¿por qué es solo ‘casi como si’ y no simplemente ‘como si’?

Contexto

Tenga en cuenta que está tratando con un archivo formateado con líneas como:

 centre (23, 41) size (19, 42) 

Suponiendo que desea leer los cuatro números, es probable que su cadena de formato sea una variante de:

 "centre (%d,%d) size (%d,%d)" 

Esto es casi un sonido Sin embargo, no hay forma con ese formato de detectar que falta el segundo paréntesis de cierre. Para asegurarse de que el paréntesis final esté presente, necesitaría una cadena de formato como:

 "centre (%d ,%d ) size (%d ,%d %1[)]" 

donde los espacios permiten muchas variaciones en el espaciado de la entrada, y el conjunto de escaneo ( %1[)] ) requiere un paréntesis cercano. Usted probaría que el scanf() devolvió 5 campos. Tenga en cuenta que si suprime la asignación con el conjunto de escaneo ( %*1[)] ), no obtendrá una indicación de error si falta el paréntesis. Es una decisión a juzgar qué tan flexible quiere ser en lo que acepta como entrada válida.

Código

 #include  int main(void) { int x1, y1, x2, y2; char str[10]; const char *data[] = { "centre ( 19, 43 ) size ( 21, 37 )", "centre (19, 43) size (21, 37)", "centre (19, 43) size (21, 37", "centre(19,43) size(21,37)", "centre(19,43) size(21,37", "centre ( 19 , 43 ) size ( 21 , 37 )", }; enum { NUM_DATA = sizeof(data) / sizeof(data[0]) }; const char *format5[] = { "centre (%d ,%d ) size (%d ,%d %[)]", "centre (%d,%d) size (%d,%d%[)]", }; enum { NUM_FORMAT5 = sizeof(format5) / sizeof(format5[0]) }; const char *format4[] = { "centre (%d ,%d ) size (%d ,%d )", "centre (%d,%d) size (%d,%d)", }; enum { NUM_FORMAT4 = sizeof(format4) / sizeof(format4[0]) }; printf("Format 5\n"); for (int i = 0; i < NUM_FORMAT5; i++) { printf("Format: <<%s>>\n", format5[i]); for (int j = 0; j < NUM_DATA; j++) { int rc; printf(" Data: <<%s>>\n", data[j]); if ((rc = sscanf(data[j], format5[i], &x1, &y1, &x2, &y2, str)) != 5) printf("!! Failed: scanf() returned %d\n", rc); else printf("== Passed: centre(%d,%d) size(%d,%d)\n", x1, y1, x2, y2); } } printf("\nFormat 4\n"); for (int i = 0; i < NUM_FORMAT4; i++) { printf("Format: <<%s>>\n", format4[i]); for (int j = 0; j < NUM_DATA; j++) { int rc; printf(" Data: <<%s>>\n", data[j]); if ((rc = sscanf(data[j], format4[i], &x1, &y1, &x2, &y2)) != 4) printf("!! Failed: scanf() returned %d\n", rc); else printf("== Passed: centre(%d,%d) size(%d,%d)\n", x1, y1, x2, y2); } } return 0; } 

Salida

 Format 5 Format: <> Data: <> == Passed: centre(19,43) size(21,37) Data: <> == Passed: centre(19,43) size(21,37) Data: <> !! Failed: scanf() returned 4 Data: <> == Passed: centre(19,43) size(21,37) Data: <> !! Failed: scanf() returned 4 Data: <> == Passed: centre(19,43) size(21,37) Format: <> Data: <> !! Failed: scanf() returned 2 Data: <> == Passed: centre(19,43) size(21,37) Data: <> !! Failed: scanf() returned 4 Data: <> == Passed: centre(19,43) size(21,37) Data: <> !! Failed: scanf() returned 4 Data: <> !! Failed: scanf() returned 1 Format 4 Format: <> Data: <> == Passed: centre(19,43) size(21,37) Data: <> == Passed: centre(19,43) size(21,37) Data: <> == Passed: centre(19,43) size(21,37) Data: <> == Passed: centre(19,43) size(21,37) Data: <> == Passed: centre(19,43) size(21,37) Data: <> == Passed: centre(19,43) size(21,37) Format: <> Data: <> !! Failed: scanf() returned 2 Data: <> == Passed: centre(19,43) size(21,37) Data: <> == Passed: centre(19,43) size(21,37) Data: <> == Passed: centre(19,43) size(21,37) Data: <> == Passed: centre(19,43) size(21,37) Data: <> !! Failed: scanf() returned 1 

Observe cómo las cadenas de formato en ‘Formato 4’ aceptan los datos cuando falta el segundo paréntesis de cierre. A pesar de que falta el carácter, se cumplen las 4 especificaciones de conversión. Los formatos ‘Formato 5’ rechazan esas líneas de datos.

El código de ejemplo y los datos no lo demuestran, pero el código también leería varios paréntesis cercanos (porque usa %[)] ). Esto podría evitarse usando %1[)] para estipular que solo un paréntesis cerrado se encuentra al final. También puede usar la especificación de conversión %n y un sexto argumento (otro int * ) para obtener el número de caracteres procesados. Esto le permitiría detectar dónde se detuvo la exploración y, por lo tanto, si hay caracteres sin procesar después de la entrada requerida. Tenga en cuenta que las especificaciones de conversión %n no se cuentan en el valor de retorno de scanf() et al. Este fragmento podría pegarse al final de la función main() en el código:

 printf("\nFormat 6\n"); int len, rc; const char data6[] = "centre ( 19 , 43 ) size ( 21 , 37 )))"; const char format6[] = "centre (%d ,%d ) size (%d ,%d %1[)]%n"; printf("Format: <<%s>>\n", format6); printf(" Data: <<%s>>\n", data[5]); if (sscanf(data6, format6, &x1, &y1, &x2, &y2, str, &len) != 5) printf("!! Failed: scanf() returned %d\n", rc); else printf("== Passed: centre(%d,%d) size(%d,%d) len=%d <<%s>>\n", x1, y1, x2, y2, len, &data6[len]); 

Genera la salida:

 Format 6 Format: <> Data: <> == Passed: centre(19,43) size(21,37) len=35 <<))>> 

Resumen

Si comprende por qué se obtiene cada uno de los resultados, tiene una comprensión decente de scanf() . Si no está seguro de por qué, experimente y lea la especificación (por ejemplo, POSIX sscanf() ) hasta que esté seguro de que lo entiende.

En tu caso

 char y[] = "a"; scanf("Letter: %s", y); printf("%s\n", y); 

Deberías dar una entrada como esta.

Carta: abcd

Funcionará correctamente

por ejemplo, si el scanf está escrito así

 int y; scanf("y=%d", &y); 

entonces deberías dar entrada como

y = 10

no 10

Creo que tienes lo que quieres … 🙂 Ahora disfruta