Bucle infinito en sentencia mientras

Aquí hay un fragmento de mi código

scanf("%d", &s); while(s!=1 && s!=2) { if(scanf("%d", &s) != 1) { show_warning(); //just print some info msg } } 

La idea es ejecutar la función show_warning solo si el usuario ingresa algo diferente de 1,2 y el valor ingresado es solo entero. Con el código de arriba salta en bucle infinito. ¿Cómo arreglar eso?

El problema es que la operación de entrada fallida no extrae ningún carácter de la secuencia (y seguirá leyendo la entrada no válida una y otra vez), por lo que debe vaciar la entrada manualmente. Por ejemplo:

 char buf[1000]; // ... if(scanf("%d", &s) != 1) { puts("Error, try again: "); fgets(buf, 1000, stdin); } 

Como sugerí en la otra pregunta , si usa fgets desde el principio para leer siempre una línea y procesarla más tarde, superará este problema.

(La misma filosofía es cierta en C ++: lea primero la línea completa para que la secuencia de entrada pueda avanzar y luego procese la línea para ver si es válida).

¿Por qué estás usando un bucle while? ¿Quieres show_warning (); ser llamado una vez, o repetidamente? Si respondiste una vez, solo necesitas una sentencia if.

¿Qué te hace pensar que está en bucle hasta el infinito?

Solo recibe el mensaje de advertencia cuando no ha ingresado un número porque no leyó un token.

Cambiar el && a || Sin embargo, es una forma segura de garantizar que se ejecutará hasta el infinito, ya que el bucle nunca se romperá en ese momento.

Es posible que desee un mensaje alternativo para que el usuario ingrese datos cuando ingresaron un número pero no 1 o 2?

Supongo que está teniendo problemas cuando se ingresa un número no entero. Esto se debe a que scanf deja caracteres no coincidentes en el búfer, por lo que las llamadas subsiguientes están viendo la misma entrada y bucle.

Lo que debe hacer es que si la llamada a scanf devuelve cualquier otro número, 1 es: lea ese carácter usando scanf("%c",&somechar) para que pueda imprimirlo y decirle al usuario que no lo acepta. La entrada no aceptada se habrá eliminado, por lo que la siguiente llamada a scanf le dará la siguiente entrada en lugar de la que vio en la iteración anterior.

Además, ¿qué sucede cuando ningún scanf tuvo éxito? La variable s permanece sin cambios (y quizás con un valor indefinido, si no lo inicializó). ¡Deberías configurarlo, o cambiar la condición del while !

Y realmente debería aprender a comstackr con las advertencias habilitadas y la información de depuración (por ejemplo, gcc -Wall -g en Linux) y a usar un depurador (por ejemplo, gdb en Linux)