Call menu function in another function

后端 未结 3 2020
春和景丽
春和景丽 2020-12-22 11:22

I\'m trying to call menu function in the main function and let it prompt until the user decides to quit, but seems like it\'s not giving me response.. I\'m new at this websi

3条回答
  •  庸人自扰
    2020-12-22 11:53

    Just a few additional cleanups. You need to determine how to handle the user canceling input by generating a manual EOF with Ctrl+d (or Ctrl+z on windoze). Since you are returning an int value, you can easily return -1 for your EOF case.

    Also, how many calls to printf do you need to make? One is enough, e.g.

    int menu (void)
    {
        int rtn, choice;    /* scanf return, menu choice */
    
        for (;;) {  /* loop until valid input or EOF displaying menu */
            printf ("\nContact Management System\n"
                    "-------------------------\n"
                    " 1. Display contacts\n"
                    " 2. Add a contact\n"
                    " 3. Update a contact\n"
                    " 4. Delete a contact\n"
                    " 5. Search contacts by cell phone number\n"
                    " 6. Sort contacts by cell phone number\n"
                    " 0. Exit\n\n"
                    "Select an option:> ");
    
            rtn = scanf ("%d", &choice);    /* save scanf return */
    
            if (rtn == 1 && 0 <= choice && choice <= 6) /* good value, break */
                break;
            else if (rtn == EOF) {  /* user canceled input, return -1 */
                fprintf (stderr, "(user canceled input).\n");
                return -1;
            }
            empty_stdin();  /* empty_stdin for rtn = 0 case */
            fprintf (stderr, " error: invalid input.\n");
        }
        empty_stdin();  /* empty_stdin after good value */
    
        return choice;  /* return choice to user */
    }
    

    The C switch function provides case-fallthrough until a break statement is encountered. You can use this to your advantage in your CMS function until you fill all case: statements. You can continue to use fallthrough to handle the 0 - exit and handle the EOF (user canceled input) return from menu(), e.g.

    void cms (void)
    {
        for (;;) {          /* loop continually calling menu */
            int choice = menu();
            char c;
            switch (choice) {
                case 1:
                case 2:
                case 3:     /* use case-fallthrough until setup */
                case 4:
                case 5:
                case 6:
                    printf("<<< Feature %d is unavailable >>>\n", choice);
                    break;
                case 0:
                    printf ("exit program [y/n]: ");    /* confirm exit */
                    if (scanf (" %c", &c) == EOF) {     /* handle EOF  */
                        fprintf (stderr, "(user canceled input).\n");
                        return;
                    }
                    empty_stdin();
                    if (c == 'N' || c == 'n') {     /* handle no exit */
                        continue;
                        break;
                    }
                case -1:        /* fallthrough yes exit or EOF in menu */
                    return;
                    break;
            }
        }
    }
    

    Putting it altogether, you can create a fairly robust little menu system, e.g.

    #include 
    
    void empty_stdin (void)
    {
        for (int c = getchar(); c != '\n' && c != EOF; c = getchar()) {}
    }
    
    int menu (void)
    {
        int rtn, choice;    /* scanf return, menu choice */
    
        for (;;) {  /* loop until valid input or EOF displaying menu */
            printf ("\nContact Management System\n"
                    "-------------------------\n"
                    " 1. Display contacts\n"
                    " 2. Add a contact\n"
                    " 3. Update a contact\n"
                    " 4. Delete a contact\n"
                    " 5. Search contacts by cell phone number\n"
                    " 6. Sort contacts by cell phone number\n"
                    " 0. Exit\n\n"
                    "Select an option:> ");
    
            rtn = scanf ("%d", &choice);    /* save scanf return */
    
            if (rtn == 1 && 0 <= choice && choice <= 6) /* good value, break */
                break;
            else if (rtn == EOF) {  /* user canceled input, return -1 */
                fprintf (stderr, "(user canceled input).\n");
                return -1;
            }
            empty_stdin();  /* empty_stdin for rtn = 0 case */
            fprintf (stderr, " error: invalid input.\n");
        }
        empty_stdin();  /* empty_stdin after good value */
    
        return choice;  /* return choice to user */
    }
    
    void cms (void)
    {
        for (;;) {          /* loop continually calling menu */
            int choice = menu();
            char c;
            switch (choice) {
                case 1:
                case 2:
                case 3:     /* use case-fallthrough until setup */
                case 4:
                case 5:
                case 6:
                    printf("<<< Feature %d is unavailable >>>\n", choice);
                    break;
                case 0:
                    printf ("exit program [y/n]: ");    /* confirm exit */
                    if (scanf (" %c", &c) == EOF) {     /* handle EOF  */
                        fprintf (stderr, "(user canceled input).\n");
                        return;
                    }
                    empty_stdin();
                    if (c == 'N' || c == 'n') {     /* handle no exit */
                        continue;
                        break;
                    }
                case -1:        /* fallthrough yes exit or EOF in menu */
                    return;
                    break;
            }
        }
    }
    
    int main (void) {
    
        cms();
        return 0;
    }
    

    Example Use/Output

    Checking the cases where user cancels input either in menu() or at the exit program [y/n]: prompt by generating a manual EOF with Ctrl+d (or Ctrl+z on windoze):

    $ ./bin/scanf_menu_cms
    
    Contact Management System
    -------------------------
     1. Display contacts
     2. Add a contact
     3. Update a contact
     4. Delete a contact
     5. Search contacts by cell phone number
     6. Sort contacts by cell phone number
     0. Exit
    
    Select an option:> (user canceled input).
    
    $ ./bin/scanf_menu_cms
    
    Contact Management System
    -------------------------
     1. Display contacts
     2. Add a contact
     3. Update a contact
     4. Delete a contact
     5. Search contacts by cell phone number
     6. Sort contacts by cell phone number
     0. Exit
    
    Select an option:> 0
    exit program [y/n]: (user canceled input).
    

    All good, now check a normal use case answering No to exit, then Yes:

    $ ./bin/scanf_menu_cms
    
    Contact Management System
    -------------------------
     1. Display contacts
     2. Add a contact
     3. Update a contact
     4. Delete a contact
     5. Search contacts by cell phone number
     6. Sort contacts by cell phone number
     0. Exit
    
    Select an option:> 4
    <<< Feature 4 is unavailable >>>
    
    Contact Management System
    -------------------------
     1. Display contacts
     2. Add a contact
     3. Update a contact
     4. Delete a contact
     5. Search contacts by cell phone number
     6. Sort contacts by cell phone number
     0. Exit
    
    Select an option:> 0
    exit program [y/n]: n
    
    Contact Management System
    -------------------------
     1. Display contacts
     2. Add a contact
     3. Update a contact
     4. Delete a contact
     5. Search contacts by cell phone number
     6. Sort contacts by cell phone number
     0. Exit
    
    Select an option:> 0
    exit program [y/n]: y
    

    Finally an invalid entry case:

    $ ./bin/scanf_menu_cms
    
    Contact Management System
    -------------------------
     1. Display contacts
     2. Add a contact
     3. Update a contact
     4. Delete a contact
     5. Search contacts by cell phone number
     6. Sort contacts by cell phone number
     0. Exit
    
    Select an option:> My dog has fleas!
     error: invalid input.
    
    Contact Management System
    -------------------------
     1. Display contacts
     2. Add a contact
     3. Update a contact
     4. Delete a contact
     5. Search contacts by cell phone number
     6. Sort contacts by cell phone number
     0. Exit
    
    Select an option:> -1
     error: invalid input.
    
    Contact Management System
    -------------------------
     1. Display contacts
     2. Add a contact
     3. Update a contact
     4. Delete a contact
     5. Search contacts by cell phone number
     6. Sort contacts by cell phone number
     0. Exit
    
    Select an option:> 7
     error: invalid input.
    
    Contact Management System
    -------------------------
     1. Display contacts
     2. Add a contact
     3. Update a contact
     4. Delete a contact
     5. Search contacts by cell phone number
     6. Sort contacts by cell phone number
     0. Exit
    
    Select an option:> 4
    <<< Feature 4 is unavailable >>>
    

    While not an error, the standard coding style for C avoids the use of camelCase or MixedCase variable names in favor of all lower-case while reserving upper-case names for use with macros and constants. It is a matter of style -- so it is completely up to you, but failing to follow it can lead to the wrong first impression in some circles.

提交回复
热议问题