0

I am kind of a beginner and have a little problem when trying to loop a menu.

Let's take this for example:

int option = 0;

do {

printf("Menu\n");
printf("[1] Insert\n");
printf("[2] List\n");
printf("[0] Exit\n");
printf("\nOption: ");
scanf("%i",&option);

switch(option)
{
    case 1: {
    // code
    break; }

    case 2: {
    // code
    break; }

    default: {
    // error
    }
}

} while(option != 0);

This will work for numbers, yet, as the option is an integer, if the user types a text, such as "a" or "owkefok" or even "ewf432k", the program will just break;

How do I give an error such as if(containstcharacters) then(error) while repeating the menu? Is it possible without changing the option to char?

  • The `scanf()` function will return the number of input items successfully matched and assigned. So you could check its return value, and just print a message indicating an error if the value is not 1. You'd also want to add `&& num_converted > 0` or something similar to the condition on your `while` loop. – eddiem Nov 11 '16 at 22:31

2 Answers2

0

You can check for return value of scanf(). Like this :

int num;

if(scanf("%d%c", &num) != 1)
    printf("failure\n");
else
    printf("valid integer followed by enter key\n");

On success, the function returns the number of items successfully read. This count can match the expected number of readings or fewer, even zero, if a matching failure happens. In the case of an input failure before any data could be successfully read, EOF is returned.

In simple words, if it can read your user input it will return the number of item it could read successfully.

So in your case the code will be :

    int option = 0;

    do {

    printf("Menu\n");
    printf("[1] Insert\n");
    printf("[2] List\n");
    printf("[0] Exit\n");
    printf("\nOption: ");
    scanf("%i",&option);

    int check = scanf("%d%c", &num);

    if(check!=1) {
    //error
    }else{

    switch(option)
    {
        case 1: {
        // code
        break; }

        case 2: {
        // code
        break; }

        default: {
        // error
        }
    }

    } while(option != 0);
}
Ratul Bin Tazul
  • 2,121
  • 1
  • 15
  • 23
  • Unfortunately, the problem is that, if it doesn't successfully convert the input, the input will still be in the stream, so it will be read again the next time `scanf()` is called. http://stackoverflow.com/questions/7898215/how-to-clear-input-buffer-in-c – eddiem Nov 11 '16 at 22:44
0

Instead of

scanf("%i",&option);

use e.g.

char str_option[100];
scanf("%s", &str_option);

so you will read into a string instead to an int. Then you may extract the first character of it and convert it to its numerical value (in spite it doesn't need be a digit) by the well-known trick

option = str_option[0] - '0'    // Converts '0' to 0, '1' to 1, and so on

Then you need not change the rest of your code except for inserting in your switch statement:

case 0 : break;                 // To not fall into "default:" for error-handling 

(By the way you need not use { } in the individual cases of the switch statement as all commands are executed regardless of them until they meet break; .)

MarianD
  • 13,096
  • 12
  • 42
  • 54
  • How do you protect against an overrun on str_option[] when more than 10 chars are entered? – lyst Nov 11 '16 at 23:06
  • @lyst - Why `10` ? – MarianD Nov 11 '16 at 23:12
  • Originally your code had `str_option[]` declared as size `[10]`, now your code is using size `[100]` so the question is now - what if more than 100 chars are entered to `stdin`? It's going to buffer overrun `str_option[]`... – lyst Nov 11 '16 at 23:17
  • @lyst - Excuse me for a joke. I wanted to indicate that *this is not production-critical program*. The student knows some basic I/O functions and learns how to use them. You first programs were not bullet-proof, too, I guess. Of course, you are right. – MarianD Nov 11 '16 at 23:39