0

I've looked at questions asked on stackoverflow before, but this is my first time asking, so I apologize in advance for any format mistakes. I've been taking a class on C programming for about a month, and I've been given an assignment to use a do/while loop in my main function to loop a displayMenu(), which allows the user to input either 1, 2, or 3 to display a certain block of information.

int main(void)
{
    int option = 0;
    do
    {
        option = displayMenu();
    } 
    while (option ==  displayName() || displayColor() || displayFood());
}

//Display the menu for choosing an option or exiting the program
int displayMenu()
{
    int choice = 1;
    while (choice == 1 || 2 || 3)
    {
        puts("Choose which piece of information you would like to know:");
        printf("%s", "1 - My name, 2 - My favorite color, 3 - My favorite food\n");
        printf("%s", "Or type in any other number to exit the program:  ");
        scanf("%d", &choice);
        puts("");

        if (choice == 1)
            displayName();
        if (choice == 2)
            displayColor();
        if (choice == 3)
            displayFood();
    }
    return choice;
}

Now, I'm sure the error is somewhere within these two methods, but just in case, I'm posting the display methods.

//Function to display my name
int displayName()
{
    int value = 1;
    puts("My name is x.\n");
    return value;
}

//Function to display my favorite color
int displayColor()
{
    int value = 2;
    puts("My favorite color is y.\n");
    return value;
}

//Function to display my favorite food
int displayFood()
{
    int value = 3;
    puts("My favorite food is z.\n");
    return value;
}

If the user inputs 1, 2, or 3, the program correctly displays the information and loops to prompt the user again about inputting another value. However, if any other number is input, the program prompts the user again to input a value, when instead it should be closing the program. What am I doing wrong? I tried inserting a

else return choice;

after the first three if statements, because i thought that would be needed to break the loop, but it didn't work. Does it have something to do with my while conditions? I'm unsure if my conditions are right, (about == and || precedence and whatnot), so if someone could clarify that too it'd be nice. I know there are probably more efficient methods to executing this program, but I'm limited to what I've been taught in the class, which really isn't anything more than what I've coded.

4 Answers4

5
while (choice == 1 || 2 || 3)

is equivalent to

while ((choice == 1) || 2 || 3)

which is equivalent to

while (1)

What you want is:

while (choice == 1 || choice == 2 || choice == 3)
ouah
  • 142,963
  • 15
  • 272
  • 331
  • Ah I see, thank you! I need to review and/or/assignments again. I made this change to my code (I also changed the option == displayName || displayColor, etc.). Now if I type anything besides 1, 2, or 3, the program DOES end, but it also prints out all three pieces of information before doing so. Is this because I'm returning a value in those three methods? – Kavian A Sep 24 '15 at 21:46
  • Agree with this answer I do – Just Do It Sep 24 '15 at 21:47
  • @KavianA it's because `while (option == displayName() /* ... */ )` will be evaluated a last time. You may want to change your `do .. while` loop or break immediately from the loop when you have to. – ouah Sep 24 '15 at 21:55
  • @ouah Got it, thanks! I changed that while loop to instead say `while(option == 1 || option == 2 || option == 3)` , which seems to have solved the problem – Kavian A Sep 24 '15 at 21:58
2

This line is an infite loop:

while (choice == 1 || 2 || 3)

I guess what you want is:

while (choice == 1 || choice == 2 || choice == 3)
Code Different
  • 90,614
  • 16
  • 144
  • 163
1

Ignoring the many errors in the original code, what you can do to refactor the loop logic is to use an array of function pointers:

int (*functions[])(void) = { displayName, displayColor, displayFood };

int choice = -1;
do {
    choice = get_choice(); // assuming get_choice returns an integer between 0 and 2, or -1 on error/eof.
    if (choice != -1)
        functions[choice]();

} while (choice != -1)

this will make your code more concise, provided all of your functions have the same prototype.

Snaipe
  • 1,191
  • 13
  • 25
  • I'd like to do that, but like I said at the very end, "I know there are more efficient methods to executing this program, but I'm limited to what I've been taught in the class, which really isn't anything more than what I've coded." I'm not permitted to use arrays. – Kavian A Sep 24 '15 at 21:52
  • 1
    Right, I missed that part. I guess this answer is for posterity. – Snaipe Sep 24 '15 at 21:54
  • @KavianA if you are interested of understanding what **Snaipe** said , take a look here http://stackoverflow.com/questions/32614150/clarification-on-function-pointers-in-c/32615240#32615240 – Michi Sep 24 '15 at 22:17
0

Well because you got your answer I will not try to give you another Answer which will probably be the same.

One thing you should know, what happens if the user type a letter or a number + a letter (1j) ?

You should have control of your programs when you are dealing with text menus.

Here is a better approach of your program:

#include <stdio.h>
#include <string.h>

int checkInput(int min, int max){
    int option,check;
    char c;

    do{
        printf("Choose an Option:\t");

        if(scanf("%d%c",&option,&c) == 0 || c != '\n'){
            while((check = getchar()) != 0 && check != '\n');
            printf("\tThe option has to be between %d and %d\n\n",min,max);
        }else if(option < min || option > max){
            printf("\tThe option has to be between %d and %d\n\n",min,max);
        }else{
            break;
        }
    }while(1);

    return option;
}

void quit(void){
    printf("Goodbye...\n");
}
//Function to display my name
int displayName(void){
    int value = 1;
    puts("My name is x.\n");
    return value;
}

//Function to display my favorite color
int displayColor(void){
    int value = 2;
    puts("My favorite color is y.\n");
    return value;
}

//Function to display my favorite food
int displayFood(void){
    int value = 3;
    puts("My favorite food is z.\n");
    return value;
}

int displayMenu(void);

int main(void){
    int option = 0;
    do{
        option = displayMenu();
    }
    while (option != 0);
}



//Display the menu for choosing an option or exiting the program
int displayMenu(void){
    int choice;

    do{
        puts("Choose which piece of information you would like to know:");
        printf("%s", "1 - My name\n2 - My favorite color\n3 - My favorite food\n\n");
        printf("%s", "Or type in any other number to exit the program:  ");

        choice = checkInput(0,3);
        puts("");

        if (choice == 1){
            displayName();
        }else if (choice == 2){
            displayColor();
        }else if (choice == 3){
            displayFood();
        }else if( choice == 0){
            quit();
        }

    }while (choice != 0);

    return choice;
}

probably a do{}while(); is better then while{}.

Michi
  • 5,175
  • 7
  • 33
  • 58