0

I am working on program where a list of options is displayed to the user and he would then enter an integer to specify which option he wants to select.Now I have pre-empted the situation where the user might enter an integer value apart from the valid ones. But if he enters any other value, say a character or a string, the program goes into an infinite loop with the list of options being printed infinitely. How can i rectify this? I mean, I should be able to give my user an error when for a predefined integer variable he enters a value that is not an integer.

Any help appreciated. Here is a sample code.

do{
    printf("Select appropriate option.\n");
    printf("Press 1 to do this");
    printf("Press 2 to do that.\n");
    printf("Press 3 to exit the program.\n");
    scanf("%d",&choice);
    if(choice!=1 && choice!=2 && choice!=3)
        printf("You entered an invalid choice. Please enter again.\n");
    switch(choice){
        case 1:
            //do this
             break
        case 2:
            //do that
            break;
        case 3:
            exit(1);
           }}


while(choice!=3);

So basically when a user enters a non-integer value for choice I want the program to notify the user and ask him for another input.

fts
  • 141
  • 4
  • 14

4 Answers4

1

It cannot be done with direct scanf into an integer variable. Such scanf will not only accept 1.23, it will also accept 1abcde and other inputs. scanf (and other conversion functions) reads as much as it can in accordance with the requested format. It stops when it finds something that does not satisfy format requirements and simply leaves it untouched.

If you want to perform this sort of analysis, you have to read the input as string and then parse and analyze that string manually.

A C-style code sketch (since you insist on C-style code, despite having tagged it as [C++]) might look as follows

char buffer[100]; /* 100 should be enough for everyone :) */
int n = scanf("%s", buffer);
if (n < 1)
  /* ERROR, can't read */;

char *end;
long choice = strtol(buffer, &end, 10); 
if (end == buffer || *end != '\0' || errno == ERANGE)
  /* ERROR, bad format */;

/* ... */
AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • what exactly do you do in the second part of your code, starting from `char *end` – fts Sep 22 '13 at 05:49
  • `strtol` is a function that converts a string into an integer (of type `long`). See this question http://stackoverflow.com/questions/1640720/how-do-i-tell-if-the-c-function-atoi-failed-or-if-it-was-a-string-of-zeros and my answer there. `end` is a pointer that will tell you where the conversion process stopped. By analyzing the value of that pointer you can determine whether the input string was "pure" integer or an integer followed by something else, i.e. catch and reject inputs like `1.23` and `1abcd`. – AnT stands with Russia Sep 22 '13 at 05:55
0

scanf will not consume any non-digits when converting %d. It will return 0 because it didn't convert anything, and the "bad input" will still be there waiting to be consumed. You have to consume it in some way to be ready for a valid input.

(also note you're excluding 3 in your if before testing for it in your switch)

Ben Jackson
  • 90,079
  • 9
  • 98
  • 150
0
  1. Use iostream - see http://www.cplusplus.com/reference/iostream/
  2. Having said that if you insist on using scanf - check the return value - i.e. read http://linux.die.net/man/3/scanf
Ed Heal
  • 59,252
  • 17
  • 87
  • 127
0

isdigit will check for any input that is a digit(number) type. For this include header ctype.h.

Also terminate your program using exit(0) if input is incorrect. For this include header stdlib.h.

#include<ctype.h>
#include<stdlib.h>

char c;
scanf("%c", &c);
if (isdigit(c)) 
{

case statement...
...
...
}
else
{
 printf("Wrong input");
 exit(0);
}
user1502952
  • 1,390
  • 4
  • 13
  • 27