0

How do I keep re-asking the user to enter a valid input that is an integer? I know how to validate an integer range input, but I don't know how to validate a non-integer input when prompted to enter an integer in C.

#include <stdio.h>

int main() {
    int menu;
    while(true) {
        printf("Choose a menu (1-4):\n");
        do {
            scanf("%d", &menu);
        } while(menu < 1 || menu > 4);
        if(menu == 1) {
            printf("menu 1\n");
        } else if(menu == 2) {
            printf("menu 2\n");
        } else if(menu == 3) {
            printf("menu 3\n");
        } else if(menu == 4) {
            printf("menu 4, exit\n");
            break;
        }
    }
    return 0;
}

Any help would be appreciated, I'm sorry if this is a duplicate as everytime I try to search the solution, it's on another language or the thread is asking "how to validate integer input range" instead of non-integer input.

1
  • 1
    You need to test the return value from scanf(). If it is EOF, there won't be any more input. If it is zero, then what's waiting in the input can't be interpreted as a number. You need to read past the next character, possibly up until the next newline (int c; while ((c = getchar()) != EOF && c != '\n') ;). Commented Apr 10, 2020 at 15:49

2 Answers 2

1

if you want to know when the user has given a non-integer input, a way of doing that is as follows:

char number; /* assuming you'll only need numbers 0-9 */
int menu;

while (true)
{
  scanf("%c",&number);
  if (number >= '0' && number <= '9')
     break;
  else
     printf("The input is not an integer\n");
 }

menu = number - '0' ;
/* write rest of the code here */

If the input is 1 - 999, you can use this:

char *s = malloc(sizeof(char)*4);

while (true)
{
  scanf("%s", s);
  is_int = true;
  menu = 0;
  if (s[3] != '\0')
  {
    printf("integer bigger than 999 not allowed, input again\n");
    continue;
  }
  for (int itr = 0; s[itr] != '\0'; itr++)
    if (s[itr] >= '0' && s[itr] <= '9')
    {
      menu = menu*10 + s[itr]-'0';
    }
    else
    {
      is_int = false;
      printf("not a valid integer, input again\n");
      break;
    }

  if (is_int && menu != 0)
  break;
}
Sign up to request clarification or add additional context in comments.

8 Comments

This works, but do you happen to know how to do that if my input range is (1-999)?
@baronoke I have added some extra code, you can check
Is it possible to input an integer range such as 1-100 with your second algorithm? I tried, but it seems impossible due to array size and how ASCII works
@baronoke yes, I tried this code on an online gdb compiler for one digit, two digit and three digit numbers, it worked fine. Are you getting any error? can you share it?
I meant, is it possible to turn this algorithm into a 1-100 integer range, instead of 0-999
|
0

Separate input from parsing.

Consider a helper function. Use fgets() to read, then parse.

// return 0 on success, EOF on end of file
int read_int(const char *prompt, int min, int max, &val) {
  #define LINE_N 100
  while (1) {
    fputs(prompt, stdout);
    fflush(stdout);

    char buf[LINE_N];
    if (fgets(buf, sizeof buf, stdin) == NULL) {
      return EOF;
    }

    char *endptr;
    errno = 0;
    long val = strtol(buf, &endptr, 0);
    // Validate an integer was read and if it is in range
    if (endptr > buf && errno==0 && val >= min && val <= max) {
      return (int) val;
    }
  }
}

Usage

int menu;
if (get_int("Choose a menu (1-4):\n", 1, 4, &menu) == EOF) {
  printf("Input closed\n");
  return 0;
}

if(menu == 1) {
...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.