0

I'm new here and I'm also very new to programming
I'm trying to make a menu interface that loops back to the beginning after i input something
This is my code

#include <stdio.h>
#include <stdlib.h>

int x;
int main()
{MENU:
    printf("Welcome to our menu\n");
    printf("What do you want to do ?\nSelect your option\n\n");
    printf("1. Binary to decimal converter\n");
    printf("2. Lorem ipsum\n");
    printf("3. Lorem ipsum\n");
    printf("4. About us\n");
    printf("5. Quit\n\n");

    printf("Input your option:");
    scanf("%d",&x);
    printf("\n");

    if (x==1){
        printf("This module doesn't exist yet\n\n");

        goto MENU;

    }
    else if (x==2){
        printf("This module doesn't exist yet\n\n");
        goto MENU;
    }
    else if (x==3){
        printf("This module doesn't exist yet\n\n");
        goto MENU;
    }
    else if (x==4){
        printf("About us\n\n");
        printf("Team Members");
        goto MENU;
    }
    else if (x==5){
        printf("Thank you for using this program");
        exit(0);
    }
    else{
        printf("Invalid input");
        goto MENU;
    }


}

The problem here now is that whenever I input something other than 1 to 5 the whole program will loop non-stop. Why is that ? What can I do about it ?

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536

2 Answers2

-1

The OP is getting infinite loop when alphabetic character is entered. To avoid that you can get string input (maybe fgets) and check if all input characters are digit and then convert it to int using atoi etc.

Codewise you can do something like this:-

char numbuf[MAX_LEN];
int op,success=0;
while( fgets(numbuf,sizeof numbuf, stdin) ){
   if(sscanf(numbuf, "%d",&op) == 1){
       success=1;
       break;
   }else
     fprintf(stderr,"%s","Error in input, give right one\n");
}
if( success )
// At this point you are sure that you have an int in `op`
success = 0;

Full code will be something like this:-

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 100
int x;
int main()
{MENU:
    printf("Welcome to our menu\n");
    printf("What do you want to do ?\nSelect your option\n\n");
    printf("1. Binary to decimal converter\n");
    printf("2. Lorem ipsum\n");
    printf("3. Lorem ipsum\n");
    printf("4. About us\n");
    printf("5. Quit\n\n");

    printf("Input your option:");
    char numbuf[MAX_LEN];
    int success = 0;
    while( fgets(numbuf,sizeof numbuf, stdin) ){
       numbuf[strcspn(numbuf, "\n")] = 0;
       if(sscanf(numbuf, "%d",&x) == 1){
         success = 1;
         break;
       }
       else
         fprintf(stderr,"%s","Error in input, give right one\n");
    }
    if( success == 0){
        exit(1);
    }
    success = 0;
    if (x==1){
        printf("This module doesn't exist yet\n\n");

        goto MENU;

    }
    else if (x==2){
        printf("This module doesn't exist yet\n\n");
        goto MENU;
    }
    else if (x==3){
        printf("This module doesn't exist yet\n\n");
        goto MENU;
    }
    else if (x==4){
        printf("About us\n\n");
        printf("Team Members");
        goto MENU;
    }
    else if (x==5){
        printf("Thank you for using this program");
        exit(0);
    }
    else{
        printf("Invalid input");
        goto MENU;
    }


}

Still I don't understand why the infinite loop?

scanf consumes input if it matches format string. Here it doesn't. So scanf stops consuming it. The non-matching input is still in the input buffer. As a result, it is being skipped and you get the propmpt frequently. You can also get rid of this by clearing the input buffer.

Use of goto is not something wrong but it generates code that is hard to maintain and debugging is much more difficult. We can use series of if else to simple switch-case statement that is much more clear to understand. Look at this code to notice these two things.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 100

int main()
{
    int x;
    while(1){
        printf("Welcome to our menu\n");
        printf("What do you want to do ?\nSelect your option\n\n");
        printf("1. Binary to decimal converter\n");
        printf("2. Lorem ipsum\n");
        printf("3. Lorem ipsum\n");
        printf("4. About us\n");
        printf("5. Quit\n\n");

        printf("Input your option:");
        char numbuf[MAX_LEN];
        int success = 0;
        while( fgets(numbuf,sizeof numbuf, stdin) ){
           numbuf[strcspn(numbuf, "\n")] = 0;
           if(sscanf(numbuf, "%d",&x) == 1){
             success = 1;
             break;
           }
           else
             fprintf(stderr,"%s","Error in input, give right one\n");
        }
        if( success == 0){
            exit(1);
        }
        success = 0;
        switch(x){
            case 1:
            case 2:
            case 3: printf("This module doesn't exist yet\n\n");
                    continue;
            case 4: printf("About us\n\nTeam Members");
                    continue;
            case 5: printf("Thank you for using this program");
                    exit(0);
            default:printf("Invalid input"); 
        }
    }
    return 0;
}

Jokes apart:

enter image description here

user2736738
  • 30,591
  • 5
  • 42
  • 56
  • See also [What is the effect of trailing white space in a scanf() format string?](https://stackoverflow.com/questions/19499060/what-is-the-effect-of-trailing-white-space-in-a-scanf-format-string) – Myst Nov 11 '17 at 14:55
  • Suggest `fgets` and `sscanf` and check the return value from `sscanf` which should be `1`. – Weather Vane Nov 11 '17 at 14:58
  • That works if you use `x` to match OP, but there is no need to remove the trailing newline. But the `while` needs better flow control, seeing as under it it says `// is OK` but not if `NULL` comes from `fgets`. – Weather Vane Nov 11 '17 at 15:11
  • @WeatherVane.: Thanks for the suggestion..please let me know if there is some scope to improve – user2736738 Nov 11 '17 at 15:24
  • It will really help me if I get to know why I am downvoted. – user2736738 Nov 14 '17 at 18:17
  • 1
    I find your answer most helpful. Not sure who downvoted it or why. – Uberheropatapon Nov 20 '17 at 01:56
-1

You can make it simpler by making use of a do while loop and switch case in it.

Try this

int main()
{
int x;
do
{
    printf("Welcome to our menu\n");
    printf("What do you want to do ?\nSelect your option\n\n");
    printf("1. Binary to decimal converter\n");
    printf("2. Lorem ipsum\n");
    printf("3. Lorem ipsum\n");
    printf("4. About us\n");
    printf("5. Quit\n\n");

    printf("Input your option:");
    scanf("%d",&x);
    printf("\n");

    //Switch statement
    switch(x)
    {
    case 1: printf("This module doesn't exist yet\n\n");
            break;
    case 2: printf("This module doesn't exist yet\n\n");
            break;
    case 3: printf("This module doesn't exist yet\n\n");
            break;
    case 4: printf("About us\n\n");
            printf("Team Members");
            break;
    case 5: return 0;
    default: printf("Invalid input");
    }
}while(1);
}   
Frank
  • 9
  • 3