Thread: Menu stuff

  1. #1
    Unleashed
    Join Date
    Sep 2001
    Posts
    1,765

    Menu stuff

    I have a Menu program that's fairly large and uses goto statements. It works fine this way. I want to get the goto statements out of the code. For the past ( I lost count ) how many hours I have been STFM, searching the board history, and tinkering with small programs to try and figure out a way to do it for ths program. I have tried if, while, and function tests galore.

    Program is setup the following way:
    == menu 1 ==
    sub menu 1
    sub menu 2
    sub menu 3

    == execution menus ==
    A choice between 3 executions of external programs through a predifined function with the selection's specific arguments passed to it.

    Some sub menus lead to further sub menus, while others present a choice of options to pass to a command line program(execution menu). It's sort of like a front end for a program that has no interface.

    I had the program working "almost" to perfection with a switch / case structure.

    case 'b':
    mainmenu();
    Go back to previous menu

    default:
    sub_menu1();
    Undefined selection, repeat menu

    case 27:
    break;
    Escape was chosen, close program.

    I was using getch() to grab the selection, and char choice; to hold it. The program didn't seem to like the 3 choices above all that well. It got awfully buggy.

    If anyone can help or point out some ideas or solutions, it'd be appreciated. I know I don't want to use goto statements, that's for sure.
    The world is waiting. I must leave you now.

  2. #2
    Has a Masters in B.S.
    Join Date
    Aug 2001
    Posts
    2,263
    well i'm not sure if this is what your asking but i'll give it a try!

    heres some hopefully relevant ~ pseudocode!

    Code:
    // or const if you desire
    #define CLOSE_PROGRAM 27 //??
    #define MAIN_MENU 'b' //???
    
    int menu1(void??)
    
    int main(void)
    {
        int menuret;
        while(!quit)
        {
            print menu;
            get selection
            switch(selection)
            {
                case menu1:
                    menuret = menu1();
                    break;
                case menu2:
                    menuret = menu2();
                    break;
                ect..
            }
            switch(menuret)
            {
                case CLOSE_PROGRAM:
                    quit = true;
                    break;
                case MAIN_MENU:
                    continue;  // skip the rest of the loop?
                    break;
                ect...
            }
        }
    }
    
    int menu1(void??)
    {
        while(1)  // exiting is done through the case loop forever
        {
            print menu;
            get selection
            switch(selection)
            {
                case 'b':
                    return MAIN_MENU;
                case 27:
                    return CLOSE_PROGRAM;
                ect..
                default:
                    printf("Invalid selection");
                    continue; // skip the rest of the loop??
            }
        }
    
    }
    i hope this is helpful!
    ADVISORY: This users posts are rated CP-MA, for Mature Audiences only.

  3. #3
    Unleashed
    Join Date
    Sep 2001
    Posts
    1,765
    I believe I have figured it out.

    Code:
    #include <stdio.h>
    #include <conio.h>
    #include <clrscr.h>
    
    int menu()
    {
        clrscr();
        printf("1  Hello message\n");
        printf("2  Sub menu\n\n");
        printf("Escape exits\n\n");
        return 0;
    }
    
    int menu2()
    {
        clrscr();
        printf("1  Hello message 2\n");
        printf("2  Back\n\n");
        printf("Escape exits\n\n");
        return 0;
    }
    
    int message()
    {
        char sub1_choice;
        while(menu() == 0)
        {
                sub1_choice=getch();
                switch(sub1_choice)
                {
                    case '1':
                    printf("hello message");
                    getch();
                    message();
                    break;
                                
                    case '2':
                    message2();
                    break;
                
                    default:
                    message();
                    break;
                
                    case 27:
                    break;
                }
                break;
        }
        return 0;
    }
    
    int message2()
    {
        char sub2_choice;
        while(menu2() == 0)
        {
                sub2_choice=getch();
                switch(sub2_choice)
                {
                    case '1':
                    printf("Hello message 2");
                    getch();
                    message2();
                    break;
                    
                    case '2':
                    message();
                    break;
                    
                    default:
                    message2();
                    break;
                    
                    case 27:
                    break;
                }
                break;
        }
        return 0;
    }    
    
    int main()
    {
        message();
        return 0;
    }
    Excuse the long code.

    I think I was getting bad program flow. What I mean is, after switching between menu after menu, and executing options, the escape option ( terminate program from anywhere ) was buggy. I simply had a problem setting up the navigation for multiple sub menus, with an escape option terminating, and the default repeating the same menu. If this small example were to be expanded, would there be any flaws? Are there any flaws now?
    The world is waiting. I must leave you now.

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Are there any flaws now?
    It looks okay. What compiler do you use though? I don't recall a <clrscr.h> for any compiler I've seen.

    -Prelude
    My best code is written with the delete key.

  5. #5
    Unleashed
    Join Date
    Sep 2001
    Posts
    1,765
    I use MingW / gcc. Clrscr.h contains the windows clear screen option which is listed in the FAQ. Is this the correct way to do it, or should I compile and link it sperately?
    The world is waiting. I must leave you now.

  6. #6
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    here's an example of a "switchboard" mechanism for navigation.

    One drawback here is you have to reserve certain numbers for proper switching...but with a little work, you can easily overcome this too...try it out.




    Code:
    int MainMenu();
    int Buy();
    int Sell();
    int Trade();
    
    
    
    int main()
    {
    
    return MainMenu();
    
    }
    
    
    
    int MainMenu()
    {
    printf(
    "Welcome To The Main Menu"
    "-----------------------------------\n\n\n"
    "1) Buy      \n"
    "2) Sell      \n"
    "3) Trade   \n"
    "4) Exit      \n"
    "\n\n\n");
    
    int choice = getch();
     
    do{
    
    switch( choice )  {
    
    case '1': choice = Buy();
    break;
    case '2': choice = Sell();
    break;
    case '3': choice = Trade();
    break;
    case '5: choice = MainMenu();
    break;
    
    default: choice = 0;
    }
    
    }while(choice);
    
    return choice;
    }
    
    
    
    int Buy()
    {
    printf(
    "Welcome To The Buying Menu"
    "-----------------------------------\n\n\n"
    "1) Buy Again     \n"
    "2) Sell      \n"
    "3) Trade   \n"
    "4) Exit      \n"
    "5) Back To Main     \n"
    
    "\n\n\n");
    
    return getch();
    }
    
    
    int Sell()
    {
    printf(
    "Welcome To The Selling Menu"
    "-----------------------------------\n\n\n"
    "1) Buy      \n"
    "2) Sell More     \n"
    "3) Trade   \n"
    "4) Exit      \n"
    "5) Back To Main     \n"
    
    "\n\n\n");
    
    return getch();
    }
    
    
    
    int Trade()
    {
    printf(
    "Welcome To The Trading Menu"
    "-----------------------------------\n\n\n"
    "1) Buy      \n"
    "2) Sell      \n"
    "3) Trade Again \n"
    "4) Exit      \n"
    "5) Back To Main     \n"
    "\n\n\n");
    
    return getch();
    }
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  7. #7
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    clrscr() is in conio.c (not conio.h) on my compiler. Yours may be similar...
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  8. #8
    Unleashed
    Join Date
    Sep 2001
    Posts
    1,765
    Sebastiani,
    I got the code I posted working. The clear screen file I was using was one I created myself.
    The world is waiting. I must leave you now.

  9. #9
    Has a Masters in B.S.
    Join Date
    Aug 2001
    Posts
    2,263
    while it works there are several possible problems?

    1. message2() needs a prototype!

    2. while this may be what you want im not sure so...

    i don't know if your looking for recursion or not, but message() is a recursive function,
    which can lead to a pretty large stack, and possible slower execution.

    what could actually be done is to use a continue or break statement which would achieve the same effect.

    Code:
    int message()
    {
        char sub1_choice;
        while(menu() == 0)
        {
                sub1_choice=getch();
                switch(sub1_choice)
                {
                    case '1':
                    printf("hello message");
                    getch();
                    break;
                                
                    case '2':
                    message2();
                    break;
                
                    default:
                    break;
                
                    case 27:
                    return 0;
                }
        }
        return 0;
    }

    third after case 27: it should be return 0; not break; since break only breaks out of the switch not the loop!

    and there were some extra breaks outside of the switch()

    i couldn't get case 27: to work but case VK_ESCAPE does???? im not sure about the why on this one.

    ok and lastly with message2() again we have the problem of recursion!
    it also calles message() which could be done by returning back to message() instead and avoiding the possible cost of recursion.

    Code:
    int message2()
    {
        char sub2_choice;
        while(menu2() == 0)
        {
                sub2_choice=__getch();
                switch(sub2_choice)
                {
                    case '1':
                    printf("Hello message 2");
                    getch();
                    break;
                    
                    case '2':
                    return 0;
                    
                    default:
                    break;
                    
                    case 27:
                    return 0;
    //              exit(0); //???? if exit program instead of just the function?
                }
        }
        return 0;
    }
    otherwise they look fine! the message functions calling would seem logical it can be problematic if it was not your intention!

    hope this is helpful!

    >
    Is this the correct way to do it, or should I compile and link it sperately?
    <

    as long as its only declared in the .h other wise your gonna get link errors!

    read Salems post about this he explains it better than me.

    http://www.cprogramming.com/cboard/s...5&pagenumber=2

    i didnt realize quite what you were asking last time!
    Last edited by no-one; 04-27-2002 at 08:43 PM.
    ADVISORY: This users posts are rated CP-MA, for Mature Audiences only.

  10. #10
    Comment your source code! Lynux-Penguin's Avatar
    Join Date
    Apr 2002
    Posts
    533
    Originally posted by no-one
    ect..
    no offense, or any relation to original post
    but for furture refrence it is actually etc.
    which is latin for
    et cetera or "and continuing"
    Asking the right question is sometimes more important than knowing the answer.
    Please read the FAQ
    C Reference Card (A MUST!)
    Pointers and Memory
    The Essentials
    CString lib

  11. #11
    Unleashed
    Join Date
    Sep 2001
    Posts
    1,765
    no offense, or any relation to original post
    but for furture refrence it is actually etc.
    which is latin for
    et cetera or "and continuing"
    It's funny that you point that out. I noticed it immediately while reading. Don't pick on no-one though, sometimes I would guess that he just doesn't care about his spelling.

    To no-one:
    Anything that isn't a define I don't put in a header file. That header file wasn't a define. It contained a function . It isn't that way any longer.
    The world is waiting. I must leave you now.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 03-05-2009, 10:25 AM
  2. Systray menu messages
    By geek@02 in forum Windows Programming
    Replies: 1
    Last Post: 05-09-2005, 06:25 AM
  3. Delet Frequency in linked list
    By swishiat.com in forum C Programming
    Replies: 16
    Last Post: 12-13-2003, 02:05 AM
  4. quick question about C Dos text menu pgm i was doing
    By Shadow in forum C Programming
    Replies: 2
    Last Post: 09-16-2001, 10:26 AM