-1

Here i have a simplified piece of code that asks and displays a number on a loop, it works fine for all numbers i type in, But if i input a letter or a special character (!"£$%^&*-_=+ etc ) it goes mental and skips the input.

 #include<stdio.h>

 int number; 
 int main()
 {
     do
     {
     system("cls");
     printf("Enter a number");
     scanf("%d",&number);
     }
     while(1==1);
}

My question is, what can i do to stop this from happening?, is there some code that filters out this nonsense or is scanf pretty much worthless?

//Edit: This is somehow been marked as a duplicate, heh.

WhipItOut
  • 15
  • 7
  • 1
    http://stackoverflow.com/a/1253080/2436175 – Antonio Dec 10 '14 at 14:55
  • `scanf` returns a value, why not just check this, as you should do for all C library functions anyhow? – Jens Gustedt Dec 10 '14 at 14:57
  • @JensGustedt That requires an extra library, 1==1 is simple and straight to the point. – WhipItOut Dec 10 '14 at 14:58
  • @WhipItOut Just `1` is more simpler – Spikatrix Dec 10 '14 at 14:59
  • @JensGustedt Checked the value, if a correct int value was entered before, it's that, if not, it's 0 – WhipItOut Dec 10 '14 at 14:59
  • @WhipItOut, this is hilarious. `stdbool.h` is not a library but just an include file, meant to make your code easier to read. If you don't want to use `true` since you know what you are doing use `1` as Gopi suggests. – Jens Gustedt Dec 10 '14 at 14:59
  • @CoolGuy While(1)? Sure but coming back to this i'll be confused thinking it something like, 1 iteration of the code or whatever, i think 1==1 is better. – WhipItOut Dec 10 '14 at 15:00
  • @WhipItOut, you didn't check well enough. The manual page for `scanf` has more information that could be useful for you. – Jens Gustedt Dec 10 '14 at 15:01
  • @JensGustedt #Inlcude,stdbool.h> is what i call a library. Now, perhaps you would like to help rather than pick out minor differences in our coding techniques? – WhipItOut Dec 10 '14 at 15:02
  • 1
    If you don't understand C well enough to know what `while(1)` is doing, you definitively should use `true`. – Jens Gustedt Dec 10 '14 at 15:03
  • @JensGustedt I took 2 inputs into my code, the correct integer and the incorrect alphabetical character. What other checks could i possibly do? – WhipItOut Dec 10 '14 at 15:04
  • @JensGustedt I understand C enough to know that a while loop requires an operator in order to stop it. It's just good practice that i include one, even for a infinite loop. – WhipItOut Dec 10 '14 at 15:05
  • 1) check the return value from `scanf()` to determine its success, if not as expected (1), do not use `number`. Code needs to read the offending data in a different manner. 2) Do not use `scanf()`, use `fgets()`, then `sscanf()` the input string. – chux - Reinstate Monica Dec 10 '14 at 15:09
  • @JensGustedt LOL you mad? – WhipItOut Dec 11 '14 at 11:30

2 Answers2

2

From here:

if the input doesn't conform to the expected format scanf() can be impossible to recover sensibly [..] A "better" alternative here is to use an input function like fgets() or fgetc() to read chunks of input, then scan it with sscanf() or parse it with string handling functions like strchr() and strtol().

Community
  • 1
  • 1
Antonio
  • 19,451
  • 13
  • 99
  • 197
0

scanf with %d will fail to scan an integer and returns 0 when a character was entered. So just check if it doesn't return 1. If it doesn't , a character was entered (if it returned 0) or else, an integer was entered. Note that if EOF was encountered, scanf will return -1.

if(scanf("%d", &number) != 1)//character entered
{
    printf("Invalid input\n");
    scanf("%*s");//clear the invalid character(s) from stdin
}
else
{
    //a number was entered
}

The reason that scanf becomes "mental" and the program prints Enter a number many times when you enter a character is that when the scanf fails to scan an integer from the standard input stream(stdin), it returns 0 and the execution continues. When scanf is called the next time, it sees the characters which you had entered the last time and again fails and this process continues. To prevent it, just clear the stdin like I've done in the code above.

Another popular way of clearing the stdin is using:

int c;
while((c = getchar()) != '\n' && c != EOF);
Spikatrix
  • 20,225
  • 7
  • 37
  • 83
  • Sorry for the late reply, i wrote a thank you on your post because there was a glitch with the commenting. Anyway, it works, thank you – WhipItOut Dec 11 '14 at 11:30
  • Check for EOF. scanf(...) greater than 0 for success. If it returns 0 then the string is improperly formatted. If less than zero then it's come to the end of the file or encountered an error reading. – Samuel Danielson Dec 21 '15 at 14:56
  • @SamuelDanielson Thank You. Edited accordingly. – Spikatrix Dec 21 '15 at 15:05