Para entender cual es el problema primero debes entender como funciona scanf. Esta funcion trabaja con un buffer de entrada o lo que es lo mismo un espacio en memoria de donde obtendra su contenido. Dicho buffer puede provenir de teclado, fichero, pipe, etc (stdin). Luego la funcion scanf intenta leer el buffer segun le especificas en el formato y una vez lee satisfactoriamente, el contenido del buffer leido es consumido. El problema viene cuando scanf no es capaz de leer el buffer como le haz indicado, entonces la funcion falla y el contenido del buffer se queda intacto. En tu caso le dices a scanf que debe leer un entero "%d" pero esta falla al encontrarse con un caracter, por lo que la funcion regresa sin haber modificado el buffer de entrada. Ahora ese caracter estara en ese buffer hasta que "alguien" lo elimine o se limpie el buffer por completo, lo que hace que tu scanf se siga llamando indefinidamente.
Luego de esta teoria, la solucion al problema se reduce a simplemente asegurarte que el buffer es limpiado si tu scanf falla para evitar un loop infinito. Una posible solucion seria:
#define ENTER '\n'
#define CORRECT_INPUT_FLAG 2
char ret = '\0';
int number = 0;
if(scanf("%d%c", &number
, &ret
) != CORRECT_INPUT_FLAG
|| ret
!= ENTER
) {
while (getchar() != ENTER
) { } // limpia el buffer de caracteres invalidos }
Por otra parte scanf es inseguro, impredecible y dificil de manejar, una mejor solucion seria usar fgets()/getline() y sscanf() si necesitas parsear el contenido a variables.
Saludos