¿Por qué es necesario% hd en scanf?

Creé un progtwig muy simple con un menú, que toma un valor, luego lo memoriza en el valor de la variable local, y finalmente con la segunda opción, el progtwig imprime el valor.

mi pregunta es: ¿por qué el progtwig funciona solo si agrego una “h” al parámetro scanf? En otras palabras: ¿qué tipo de relación hay entre scanf () y mi variable de valor int local?

¡Gracias!

pS (utilicé Dev-C ++ (GCC) para comstackrlo. Con Visual Studio funciona)

#include  main () { int value = 0; short choice = 0; do { printf("\nYour Choice ---> "); scanf("%d", &choice); /* replace with "%hd" and it works */ switch (choice) { case 1: printf("\nEnter a volue to store "); scanf("%d", &value); getchar(); printf("\nValue: %d", value); break; case 2: printf("\nValue: %d", value); break; } } while (choice < 3); getchar(); } 

Con scanf , el modificador “h” indica que está leyendo un entero corto, lo que resulta ser su choice variable. Por lo tanto, “% hd” es necesario para escribir solo dos bytes (en la mayoría de las máquinas) en lugar de los 4 bytes que escribe “% d”.

Para obtener más información, consulte esta página de referencia en scanf

La choice variable es de tipo short por eso necesita el especificador %h en scanf para leerlo (de hecho, no necesita la d aquí). El tipo int solo requiere %d . Vea las notas sobre conversiones aquí.

Estás leyendo en un corto. La h es necesaria porque% d es el tamaño de un int por defecto. Vea esta página de referencia en scanf .

Parece que su problema es que la choice es short , que tiene una short (generalmente) de 2 bytes, mientras que %d espera un número entero, que es (generalmente) larga de 4 bytes … Por lo tanto, el scanf clic en la stack.

choice es short y% d especifica un int .

Cuando especifica% d, scanf tiene que asumir que el argumento asociado es un puntero a un bloque de memoria del tamaño int , y escribirá un int en él. Cuando eso suceda, es probable que se escriba en los datos adyacentes, pero no sea parte de la choice y los resultados no están definidos y probablemente no sean buenos. Si funciona en un comstackdor y no en otro, ¡eso es simplemente la naturaleza del comportamiento indefinido !

En GCC, el formato debe darle una advertencia cuando cometa este error.

Desde la comp.lang.c FAQ:

  • ¿Por qué el código no es short int s; scanf("%d", &s); short int s; scanf("%d", &s); ¿trabajo?
  • Alguien me dijo que estaba mal usar %lf con printf . ¿Cómo puede printf usar %f para el tipo double , si scanf requiere %lf ?

%d es para leer un int , no un corto. Su código nunca realmente “funcionó”: parece que en este caso no notó ninguna diferencia entre lo que quería y el comportamiento indefinido que tuvo.

El modificador para scanf para ingresar una variable de tipo short es% hd. Por lo tanto, es necesario especificar el modificador correcto.

 scanf("%d",&integer); // For integer type scanf("%hd",&short_int); // For short type 

Por lo tanto, no funciona.

Dependiendo del relleno numérico, la endiancia y otros problemas similares, puede almacenar la parte superior o inferior del valor de entrada en la opción; está almacenando el rest del valor de entrada en la memoria que puede o no estar siendo utilizado para cualquier otra cosa.