Нужно сделать меню в консольке. Помогите пожалуйста

Нужно получить что-то типо вот такого(1):
(1)

  1. Администратор
  2. Пользователь

// при нажатии 1 запрашивается пароль, это я уже сделал. Проблема вот в чем. После проверки пароля появляется следующая менюшка(2):

(2)

  1. Вывести на экран имена
  2. Вывести на экран фамилии
  3. Вывести на экран отчество
  4. Вернуться в главное меню. (1)
  5. Выйти (имеется в виду из программы вообще)

// если мы тут выбираем какой-то из пунктов то после выполнения операции должна быть возможность вернуться назад. Проблема заключается в том что я не знаю, как это сделать... чтобы можно было не ограниченное количество раз возвращаться в главное меню... По моему надо как-то зациклить... (но это лишь мои догадки, без малейшей доли представления о том как это сделать)
Помогите пожалуйста))

Думаю так сойдет. Там немножко доработать надо и все, можно юзать.

При желании можно еще сделать чтобы надписи были цветными и фон поменять.

Пароль: 11.

#include <iostream>
#include <locale>
#include <conio.h>


using namespace std;

int main()
{
    setlocale(LC_CTYPE, "Russian");

    unsigned short nNumber = 0;     
        do{system("cls");
    wcout<<L"1. Войти как администратор. "<<endl;       
    wcout<<L"2. Войти как пользователь. "<<endl<<endl;
    wcout<<L"Введите номер: ";
    cin>>nNumber;
    cin.clear();
    cin.sync(); 
    }while(nNumber!=1 & nNumber!=2);
    switch(nNumber)
    {
    case 1:
        {
    wcout<<L"Вы попытались войти как администратор."<<endl;
    const unsigned short  cnPassword = 11;
    unsigned short nPassword = 0;   
        do  
        {           
        wcout<<L"Введите пароль для получения прав администратора: ";           
        cin>>nPassword;
        cin.clear();
        cin.sync();
        if(nPassword!=cnPassword)       
        wcout<<endl<<endl<<L"\t\t\t\tПароль введен неверно!\n\t\t\t\t Повторите попытку."<<endl;        
        if(nPassword==cnPassword)
        wcout<<L"\n\t\t\tПароль введен верно!\r"<<endl;
        _getch();                           
        system("cls");      
        }while(cnPassword !=nPassword);
        unsigned short nPunkt = 0;
        do
        {
        wcout<<L"Доступные команды."<<endl
            <<L"1. Вывести на экран имена."<<endl
            <<L"2. Вывести на экран фамилии."<<endl
            <<L"3. Вывести на экран отчество."<<endl<<endl;
        wcout<<L"Введите номер команды: ";

        cin>>nPunkt;
        cin.clear();
        cin.sync();
        switch(nPunkt)
        {           
        case 1:
            wcout<<L"1. Имя"<<endl
                <<L"2. Имя"<<endl
                <<L"3. Имя"<<endl
                <<L"4. Имя"<<endl
                <<L"5. Имя"<<endl
                <<L"6. Имя"<<endl
                <<L"7. Имя"<<endl
                <<L"8. Имя"<<endl
                <<L"9. Имя"<<endl
                <<L"10. Имя"<<endl<<endl;           
            break;

        case 2: 
            wcout<<L"1. Фамилия"<<endl
                <<L"2. Фамилия"<<endl
                <<L"3. Фамилия"<<endl
                <<L"4. Фамилия"<<endl
                <<L"5. Фамилия"<<endl
                <<L"6. Фамилия"<<endl
                <<L"7. Фамилия"<<endl
                <<L"8. Фамилия"<<endl
                <<L"9. Фамилия"<<endl
                <<L"10. Фамилия"<<endl<<endl;           
            break;

        case 3:
            wcout<<L"1. Отчество"<<endl
                <<L"2. Отчество"<<endl
                <<L"3. Отчество"<<endl
                <<L"4. Отчество"<<endl
                <<L"5. Отчество"<<endl
                <<L"6. Отчество"<<endl
                <<L"7. Отчество"<<endl
                <<L"8. Отчество"<<endl
                <<L"9. Отчество"<<endl
                <<L"10. Отчество"<<endl<<endl;      
            break;

        case 4:
            break;
        case 5:
            break;
        case 6: 
            break;
        case 7:
            break;
        case 8:
            break;
        case 9:
            break;
        case 10:
            return(EXIT_SUCCESS);
            break;
        }
        _getch();
        system("cls");
        }while(nPunkt!=false);
        }

        break;
    case 2: wcout<<L"Вы вошли как пользователь. "<<endl<<endl;
        unsigned short nPunkt = 0;
        do
        {
        wcout<<L"Доступные команды: "<<endl<<endl
            <<L"1. Вывести на экран имена."<<endl
            <<L"2. Вывести на экран фамилии."<<endl
            <<L"3. Вывести на экран отчество."<<endl<<endl;
        wcout<<L"Введите номер команды: ";

        cin>>nPunkt;
        cin.clear();
        cin.sync();
        switch(nPunkt)
        {           
        case 1:
            wcout<<L"1. Имя"<<endl
                <<L"2. Имя"<<endl
                <<L"3. Имя"<<endl
                <<L"4. Имя"<<endl
                <<L"5. Имя"<<endl
                <<L"6. Имя"<<endl
                <<L"7. Имя"<<endl
                <<L"8. Имя"<<endl
                <<L"9. Имя"<<endl
                <<L"10. Имя"<<endl<<endl;           
            break;

        case 2: 
            wcout<<L"1. Фамилия"<<endl
                <<L"2. Фамилия"<<endl
                <<L"3. Фамилия"<<endl
                <<L"4. Фамилия"<<endl
                <<L"5. Фамилия"<<endl
                <<L"6. Фамилия"<<endl
                <<L"7. Фамилия"<<endl
                <<L"8. Фамилия"<<endl
                <<L"9. Фамилия"<<endl
                <<L"10. Фамилия"<<endl<<endl;           
            break;

        case 3:
            wcout<<L"1. Отчество"<<endl
                <<L"2. Отчество"<<endl
                <<L"3. Отчество"<<endl
                <<L"4. Отчество"<<endl
                <<L"5. Отчество"<<endl
                <<L"6. Отчество"<<endl
                <<L"7. Отчество"<<endl
                <<L"8. Отчество"<<endl
                <<L"9. Отчество"<<endl
                <<L"10. Отчество"<<endl<<endl;      
            break;

        case 4:
            break;
        case 5:
            break;
        case 6: 
            break;
        case 7:
            break;
        case 8:
            break;
        case 9:
            break;
        case 10:
            return(EXIT_SUCCESS);
            break;
        }
        _getch();
        system("cls");
        }while(nPunkt!=false);
        }
        return(EXIT_SUCCESS);
}

Никогда, честно говоря, не заморачивался по поводу разветвлённых меню в консольных программах, но задачка показалась занимательной. После некоторых раздумий появилось следующее решение:

#include <iostream>

using namespace std;

struct menu_item {
    const char *str;     // текст пункта меню
    void (*func)(void);  // указатель на функцию, которая будет выполняться для данного пункта меню
};

void menu(menu_item *mi, int mi_size);

void f1(void) {
    cout << "отработала f1()" << endl;
}

void f2_1(void) {
    cout << "отработала f2_1()" << endl;
}

void f2_2(void) {
    cout << "отработала f2_2()" << endl;
}

void f2(void) {
    cout << "начала работу f2()" << endl;

    menu_item menu2[] = { {"функция f2_1", f2_1}, {"функция f2_2", f2_2}, {"выход", NULL} };
    menu(menu2, sizeof(menu2) / sizeof(menu_item));

    cout << "закончила работу f2()" << endl;
}

void f3(void) {
    cout << "отработала f3()" << endl;
}

menu_item menu1[] = { {"функция f1", f1}, {"функция f2", f2}, {"функция f3", f3}, {"выход", NULL} };

void menu(menu_item *mi, int mi_size) {
    int choice;
    while (true) {
        cout << endl;
        for (int i = 0; i < mi_size; i++) {
            if (mi[i].func == 0) {
                cout << "0. " << mi[i].str << endl;
            }
            else {
                cout << i+1 << ". " << mi[i].str << endl;
            }
        }
        cout << endl << "Ваш выбор: ";
        choice = -1;
        cin >> choice;
        if (!cin) {
            cin.clear();
            cin.ignore();
        }
        if (!cin || choice < 0 || choice >= mi_size) {
            cout << "Неверный выбор! Попробуйте снова..." << endl;
            continue;
        }
        if (choice == 0) {
            break;
        }
        (mi[choice-1].func)();
    }

}


int main() {

    setlocale(LC_ALL, "Russian");

    menu(menu1, sizeof(menu1) / sizeof(menu_item));
}

Выполнено в «сишном» стиле, никакого ООП и прочих заморочек... но как прототип — потянет.

Смотреть в первую очередь структуру menu_item и функцию menu(). Остальное — обвязка.

Структура содержит указатель на «строку» меню (без номера пункта) и указатель на функцию, которая будет вызвана при выборе пункта меню. Функция, вызываемая из меню, имеет прототип void funcname(void). Если в структуре указатель на функцию равен NULL, то такой пункт меню будет помечен как 0 и предназначен для окончания работы меню. Структуры собираются в массив, который, собственно, и представляет собой меню.

Функция menu() в качестве параметров получает массив структур menu_item и размер массива. Функция в бесконечном цикле (1) выводит на экран пункты меню, (2) запрашивает у пользователя номер пункта меню с примитивной обработкой ошибок, (3) проверяет: если введён 0, то прерывает цикл и выходит из функции, (4) запускает на выполнение функцию, соответствующую выбранному пункту меню.

Как можно видеть из приведённой программы, вложенные меню (см. функцию f2()), тоже легко реализуются.

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.

Ответить

Вы можете использовать разметку markdown для оформления комментариев и постов. Используйте функцию предпросмотра для проверки корректности разметки.

Пожалуйста, оформляйте исходный код в соответствии с правилами разметки. Для того, чтобы вставить код в комментарий, скопируйте его в текстовое поле ниже, после чего выделите то, что скопировали и нажмите кнопку «код» в панели инструментов. Иначе ваш код может принять нечитаемый вид.

Либо производите оформление кода вручную, следующим образом:

``` #include <iostream> using namespace std; int main() { // ... } ```

Предпросмотр сообщения

Ваше сообщение пусто.