¿Cómo evito el Deadloop si un usuario ingresa un char en un scanf buscando un interger?

He estado buscando en la web por un tiempo, sin encontrar una respuesta satisfactoria. Ahora probaré mi suerte aquí. Así que aquí va:

En mi progtwig quiero que un usuario ingrese un número, a través del terminal, para esto uso scanf (). Bastante simple, lo sé … y lo tengo funcionando. Pero también quiero hacerlo “a prueba de idiotas”. Por lo tanto, estoy tratando de asegurarme de que si el usuario ingresa un carácter y no un interger, el progtwig no se interrumpirá. Tal como está ahora, si se ingresa un carácter, el progtwig se interrumpirá.

Mi código es:

long fs = 0; printf("Enter the samplefrequency(in Hz) and press 'ENTER': "); while(fs<=0) { scanf(" %li", &fs); if(fs <= 0) { printf("\nThe samplefrequency must be above 0 Hz. Please enter again: "); } } 

Esto seguirá imprimiendo la línea en la sentencia if. ¿Cómo evito esto?

La única manera de hacer que la entrada del usuario desde la consola sea completamente a prueba de idiotas es esta:

  • No utilice scanf .
  • Lee la entrada como una cadena, usando fgets . No lo lea como un número entero.
  • Analice esta cadena y vea si contiene un número válido.
  • Convierte la cadena en un entero usando strtol ().

cambiarlo de esta manera:

 scanf(" %li", &fs); while(fs <= 0) { printf("\nThe samplefrequency must be above 0 Hz. Please enter again: "); scanf(" %li", &fs); } 

Cuando ingrese un número incorrecto, el bucle continuará solicitando un nuevo número hasta que sea correcto.

Aquí hay un ejemplo que muestra cómo usar fgets con sscanf para resolver el problema de entrada del usuario.

La función getInputFromUser muestra prompt1 y luego usa fgets para leer una línea de entrada del usuario. (Si fgets devuelve NULL , eso indica el final del archivo del usuario, y el progtwig se cancela).

La función utiliza sscanf para convertir la entrada en un número. sscanf devuelve el número de conversiones exitosas, por lo que en este ejemplo, un valor de retorno de 1 indica que sscanf tuvo éxito. (Se puede realizar una verificación de rango adicional después de sscanf para asegurarse de que el número sea aceptable). Si falla sscanf , se muestra el segundo indicador ( prompt2 ) y la función lo intenta nuevamente.

Si y cuando el usuario comienza a ingresar un número válido, la función devolverá ese valor.

 long getInputFromUser(char *prompt1, char *prompt2) { long result = 0; char line[100]; printf("%s", prompt1); for (;;) { if (fgets(line, sizeof(line), stdin) == NULL) { // user hit the EOF key printf( "\nterminated by user...\n" ); exit(1); } if (sscanf( line, "%ld", &result) == 1 && result > 0) break; printf("%s", prompt2); } return result; } 

Llame a la función con la solicitud inicial y la solicitud para el usuario

 long fs = getInputFromUser("Enter the samplefrequency(in Hz) and press 'ENTER': ", "The samplefrequency must be above 0 Hz. Please enter again: ");