Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validate the type of input in a do-while loop C

Basically, I need to ensure that input is an integer, like so:

do {
    printf("Enter > ");
    scanf("%d", &integer);
} while (/* user entered a char instead of an int */);

I have tried various methods, but it always end up with run-time error or infinite loop when I tried to enter a char. I have knew that fflush(stdin) is an undefined behavior, which is better not to involve it in my code in order to prevent any error plus it no longer works in VS2015 due to some reasons.

The codes below are the method that I have tried:

typedef enum {false, true} bool;
int ipt;
char c;
bool wrong_ipt;

do {
    c = '\0';
    printf("Enter > ");
    scanf("%d%c", &ipt, &c); //infinite loop occurs while a char has been entered
} while (c != '\n');

do {
    c = '\0';
    printf("Enter > ");
} while (scanf("%d", &ipt) != EOF);

do {
    wrong_ipt = false;
    do {
        ipt = NULL;
        printf("Enter > ");
        scanf("%d", &ipt);
        if (ipt == NULL) {
            wrong_ipt = true;
            break;
        }
    } while (ipt == NULL);
} while (wrong_ipt);

Is there anyway other than fflush(stdin) which can be used to prevent the infinite loop when user entered a char in C?

Thank you

like image 458
Juen Khaw Avatar asked Jul 26 '15 02:07

Juen Khaw


1 Answers

The problem is that "scanf()" can leave unread data in your input buffer. Hence the "infinite loop".

Another issue is that you should validate the return value from scanf(). If you expect one integer value ... and scanf returns "0" items read ... then you know something went wrong.

Here is an example:

#include <stdio.h>

void discard_junk () 
{
  int c;
  while((c = getchar()) != '\n' && c != EOF)
    ;
}

int main (int argc, char *argv[])
{
  int integer, i;
  do {
      printf("Enter > ");
      i = scanf("%d", &integer);
      if (i == 1) {
        printf ("Good value: %d\n", integer);
      }
      else {
        printf ("BAD VALUE, i=%i!\n", i);
        discard_junk ();
      }
   } while (i != 1);

  return 0;
}

Sample output:

Enter > A
BAD VALUE, i=0!
Enter > B
BAD VALUE, i=0!
Enter > 1
Good value: 1

'Hope that helps!

like image 74
paulsm4 Avatar answered Sep 18 '22 12:09

paulsm4