Well when you input character, scanf actually tries to get those wrong character inputs from the stdin but as it is not as per the conversion specification provided it fails. And then it keeps those wrong input in the stdin. And next time the scanf fails again due to those wrong inputs. So you need to clear it before you attempt to get the input again using scanf. Also check the return value of scanf and in case it failed clear the stdin.
The provided code checks for EOF and also return value of scanf the standard says explicitly about the return value of scanf :-
7.21.6.2p16
The fscanf function returns the value of the macro EOF if an
  input failure occurs before the first conversion (if any) has
  completed. Otherwise, the function returns the number of input
  items assigned, which can be fewer than provided for, or even
  zero, in the event of an early matching failure.
The code will be something like this. (This is using scanf).
Better even use fgets. you can easily and more better way control the erro neous inputs. With fgets you will read the entire line and then parse the integer input from it using strtol or strtoul. Yes in case of integer input there will be a case there also - you need to check if the parsed long or unsigned long is of proper size so that they can be kept in int variable.