Medvednic
Medvednic

Reputation: 692

How to deal with wrong input C?

Beginner's question:

Imagine this scenario: I request the user to enter an integer (getting it by using scanf) but the user enters a character; because of that the program reaches its end... but I want to overcome it, and make the program tell him that he has provided invalid input and give the user another chance to enter an input. How can I do that?

Upvotes: 6

Views: 15839

Answers (6)

chux
chux

Reputation: 153303

Use fgets(), then sscanf() or strtol().

int number;
char ch;
char *Prompt2 = "":
do {
  printf("%sEnter number :", Prompt2);
  Prompt2 = "Invalid input\n";  // Change Prompt2 
  buffer char[50];
  if (fgets(buffer, sizeof buffer, stdin) == NULL) {
    Handle_EOF();
  }  
} while (sscanf(buffer, "%d %c", &number, &ch) != 1);

Using strtol() instead of sscanf() adds +/- overflow protection as that sets errno.

  char *endptr; 
  errno = 0;
  long number = strtol(buffer, &endptr, 10);
  if (errno || buffer == endptr || *endptr != '\n') Handle_Error(();

See Read_long() as an example of how to use this a function.

Upvotes: 5

Costis Aivalis
Costis Aivalis

Reputation: 13728

Beginners work with stdio.h, which is quite OK for homework assignments, as long as you do not expect anything fancy, like password-field entry, input editing capabilities, formatting while typing, function-key and control-key handling etc. What you can do with erroneous input is limited to the basics.

If you need to write a professional application in C, which is something we used to do in the 70's and 80's, in C, you have to avoid stdio.h and hence scanf for input. You must check what your operating environment and the community have to offer. Curses, or ncurses may help you out. In MS-DOS we used to catch interrupts in order to have absolute control over the keyboard. In Unix we were using Bill Joy's termcap or a terminfo libraries, which will allow you to control your terminal and keyboard. The vi editor, as an example, was based upon termcap and curses upon terminfo.

Keep in mind that it is not a trivial task to create a crisp Text-based User Interface, nor is it easy to totally control user's input. Fortunately it is also not a problem anymore, since Java and Swing have been around...

Upvotes: 1

Manolis Ragkousis
Manolis Ragkousis

Reputation: 665

You could read the input from the user as a string and then use strtol() to make it an integer.

int main(void)
{
  char* end;
  char number_temp[256];

  int number;  

  while(1)
  {
     puts("Give a number");
     scanf("%s",number_temp);

     number = strtol(number_temp, &end, 10);

     if (end)              //If there is an error the value of *end will be non zero
        printf("try again");
     else
        break;
  }
  return 0;
}

Upvotes: 0

Filipe Gonçalves
Filipe Gonçalves

Reputation: 21213

How about:

  int n;
  int c;
  printf("Please enter an integer: ");
  while (scanf("%d", &n) != 1) {
    while (!isspace(c = getchar()));
    ungetc(c, stdin);
    printf("You must enter a valid number. Try again.\n");
    continue;
  }

Upvotes: 1

Jonathan Leffler
Jonathan Leffler

Reputation: 753455

The basic technique is to detect the problem (unexpected return value from *scanf()), then read the rest of the line (gobble characters to newline or EOF), then resume.

Or, usually better (not least because the error reporting can report the whole line), is to use fgets() or getline() to read the whole line, then use sscanf() or other techniques to parse that line, and go from there.

Upvotes: 0

Dan
Dan

Reputation: 13160

The return value of scanf is the number of arguments successfully scanned.

Upvotes: 2

Related Questions