Usando fgets y strtol para obtener un solo entero

Estoy aprendiendo C y estoy tratando de usar fgets () y strtol () para aceptar comentarios del usuario y simplemente tomar el primer carácter. Voy a hacer un menú que permitirá al usuario seleccionar las opciones 1-3 y 4 para salir. Quiero que cada opción se seleccione solo si se seleccionan ‘1’, ‘2’, ‘3’ o ‘4’. No quiero que ‘asdfasdf’ funcione. Tampoco quiero que ‘11212’ seleccione la primera opción, ya que comienza con un 1. Creé este código hasta ahora mientras empecé a probar y, por alguna razón, aparece un bucle sobre la pregunta y proporciona un 0 a la entrada.

#include  #include  int main() { char a[2]; long b; while(1) { printf("Enter a number: "); fgets(a, 2, stdin); b = strtol(a, NULL, 10); printf("b: %d\n", b); } return 0; } 

salida

 Enter a number: 3 b: 3 Enter a number: b: 0 Enter a number: 

Debería ser:

 Enter a number: 3 b: 3 Enter a number: 9 b: 9 

Debe tener suficiente espacio para que se lea el '\n' o, de lo contrario, se quedará en el búfer de entrada y la siguiente iteración se leerá de inmediato y, por lo tanto, fgets() regresará con una cadena vacía y, por lo tanto, strtol() devuelve 0 .

Lee la documentación de fgets () , lee hasta que aparezca '\n' o hasta que el buffer esté lleno. Así que la primera vez, se detiene porque no tiene más espacio para almacenar caracteres, y luego la segunda vez todavía tiene que leer '\n' y se detiene de inmediato.

Una posible solución es boost el tamaño del búfer, de modo que el '\n' se lea y almacene en él.

Otra solución, es leer todos los caracteres restantes después de fgets() .

La segunda solución podría implementarse limpiamente leyendo un carácter a la vez, ya que solo estás interesado en el primer carácter que puedes descartar de cualquier otra cosa.

 #include  #include  int main() { int chr; while (1) { // Read the next character in the input buffer chr = fgetc(stdin); // Check if the value is in range if ((chr >= '0') && (chr <= '9')) { int value; // Compute the corresponding integer value = chr - '0'; fprintf(stdout, "value: %d\n", value); } else { fprintf(stderr, "unexpected character: %c\n", chr); } // Remove remaining characters from the // input buffer. while (((chr = fgetc(stdin)) != '\n') && (chr != EOF)) ; } return 0; }