Форум программистов, компьютерный форум CyberForum.ru

Меню на консоли - C++

Восстановить пароль Регистрация
Другие темы раздела
C++ Biginteger и переменная http://www.cyberforum.ru/cpp-beginners/thread1047016.html
Например есть такое : #include "BigIntegerLibrary.hh" BigInteger a = 65536; cout << (a * a * a * a * a * a * a * a); (prints 340282366920938463463374607431768211456) Мне необходимо объявить переменную и приравнять к 0, чтобы задать ей позже какое-то значение, (а в примере выше ей сразу присваивается значение), чтобы задать ей позже какое-то значение, напримеp:
C++ алгоритм бм кто может написать алгоритм БМ http://www.cyberforum.ru/cpp-beginners/thread1047008.html
Возврат 2 значений из функции с одним вызовом этой же функции C++
Вообщем где то в какой то игре была хукнута одна функция int function(int arg1,int arg2,int arg3); суть в чем int function(int arg1,int arg2,int arg3) { int retval = 0; // туча кода
Оператор Goto и ветвление C++
Помогите, пожалуйста, написать программу, которая сперва считывает введенное с клавиатуры число, а потом, если введено одно значение (например 10), то программа выводит 2, если введено другое значение (например, 7), то программа выводит 1, в остальных случаях программа выводит 0, без использования операторов if и switch (goto можно).
C++ Обработка символьного массива http://www.cyberforum.ru/cpp-beginners/thread1046930.html
Итак, задание: Без использования конструкции string написать программу ввода и вывода необходимого текста с клавиатуры. Ввод осуществляется до точки. а) Вывести только маленькие латинские символы, пробелы и точку. в) Вывести количество символов в введеном тексте и выведенном. г) Вывести количество слов в выведенном тексте. д) В выведенном тексте заменить на XXX каждое слово из 5 букв,...
C++ Как очистить cin? собственно защита от дурака, от пользователя требуется цифра, а он вводит букву, и все следующие cin не работают, cin.clear() не подходит, как реанимировать cin ? Добавлено через 3 минуты std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n'); вроде бы нашёл решение, но если первыми символами являются цифры, то cin все равно их записывает, как избежать этого? подробнее

Показать сообщение отдельно
Darthriddikc
10 / 10 / 0
Регистрация: 23.12.2012
Сообщений: 45
19.12.2013, 02:07     Меню на консоли
Здравствуйте! Изучаю C++, для практики ради делаю консольное меню через класс.
Может быть мне, пока что, ещё далеко до претендента на гуру по адекватной реализации алгоритмов
Вот, как я это реализовал...

classias.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include <iostream>
#include <conio.h>
#include <windows.h>
using namespace std;
 
#ifndef CPP_MENU
#define CPP_MENU
 
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
 
class Menu{
 
///////////////////////// * СТЕК * ///////////////////////////
    // Структура стека и функции работы с ним, хранит предыдущие директории(меню)
    static struct STACK_DIR{
        static int num;
        Menu *elem;
        STACK_DIR *last;
    }*stackDir;
 
    void push(STACK_DIR* &stack, Menu* i){
        STACK_DIR *last_stack=stack;
        stack=new STACK_DIR;
        STACK_DIR::num++;
        stack->elem=i;
        stack->last=last_stack;
    }
 
    Menu* pop(STACK_DIR* &stack){
        Menu *pop_elem=stack->elem;
        STACK_DIR *temp=stack;
        stack=stack->last;
        delete temp;
        STACK_DIR::num--;
        return pop_elem;
    }
//////////////////////////////////////////////////////////////
 
    // LINES_Data - структура данных одной строки в объекте
    struct LINES_Data{
        char name[32]; // Название строки
        Menu *nextDir; // Куда эта строка ведёт
    }*lineData;
 
    static Menu *delLines; // для "подтирания" оставшихся символов предыдущего меню
    unsigned short lines; // число строк в одной директиве
    short position; // позиция, где на данный момент находится выбор
 
    // GoToXY - метод который будет устанавливать "каретку" на поле консоли (x-столбец y-строка)
    // по сути с помощью него будет очищаться экран от старого меню, но в отличии от CLS будет замещать старое меню новым
    void GoToXY(unsigned x, unsigned y){
        COORD coord = { static_cast<SHORT>(x), static_cast<SHORT>(y) };
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    }
 
public:
 
    static unsigned Y_Console_pos; //положение "каретки" по X
    static unsigned X_Console_pos; //положение "каретки" по Y
 
    //В конструктор задаётся число строк менюшки и 2 необязательных параметра - положение X Y (по умолчанию 0,0)
    Menu(unsigned lines, unsigned X_Console_pos=Menu::X_Console_pos, unsigned Y_Console_pos=Menu::Y_Console_pos){
        Menu::Y_Console_pos=Y_Console_pos;
        Menu::X_Console_pos=X_Console_pos;
        position=0;
        char ch_i[4];
        Menu::lines=lines;
        lineData=new LINES_Data[lines];
        for(int i=0; i<lines; i++){
            strcpy(lineData[i].name,"ITEM_");
            sprintf(ch_i,"%d",i+1);
            strcat(lineData[i].name,ch_i);
            lineData[i].nextDir=this;
        }
    }
    ~Menu(){
        delete []lineData;
    }
 
    // startMenu - запуск меню
    void startMenu(){
        int key; // код клавиши
        if(delLines){
            for (int i=0; i<delLines->lines; i++){
                GoToXY(X_Console_pos,Y_Console_pos+i);
                for(int j=0; j<strlen(delLines->lineData[i].name); j++)
                    cout<<' ';
                cout<<endl;
            }
        }
        while(1){
            if(position<0)
                position=lines-1;
            if(position>=lines)
                position=0;
            for (int i=0; i<lines; i++){
                GoToXY(X_Console_pos,Y_Console_pos+i);
                if(i==position)
                    SetConsoleTextAttribute(hConsole, 0+(7<<4));
                cout<<lineData[i].name<<endl;
                SetConsoleTextAttribute(hConsole, 7+(0<<4));
            }
            key=_getch();
            if(key==27){ // Esc
                if(STACK_DIR::num){
                    delLines=this;
                    pop(stackDir)->startMenu();
                }
                break;
            }
            if(key==224){
                key=_getch();
                switch (key){
                case 72: // стрелка вверх
                    position--;
                    break;
                case 80: // стрелка вниз
                    position++;
                    break;
                }
            }
            if(key==13){ // Enter
                if(!lineData[position].nextDir)
                    break;
                if(lineData[position].nextDir!=this){
                    delLines=this;
                    if(STACK_DIR::num && stackDir->elem==lineData[position].nextDir){
                        pop(stackDir)->startMenu();
                        break;
                    }
                    push(stackDir,this);
                    lineData[position].nextDir->startMenu();
                    break;
                }
            }
        }
    }
 
    // lineInit - метод инициализации строки (номер строки, куда она пошлёт, имя строки)
    void lineInit(int i, Menu* nextDir, char *name=0){
        if(i>lines-1){
            cerr<<"Line "<<i<<" Error! Overflowing lines! Max="<<lines-1<<endl;
        }
        else{
            if(name)
                strcpy(lineData[i].name,name);
            lineData[i].nextDir=nextDir;
        }
    }
};
 
unsigned Menu::X_Console_pos=0;
unsigned Menu::Y_Console_pos=0;
int Menu::STACK_DIR::num=0;
Menu::STACK_DIR *Menu::stackDir=0;
Menu *Menu::delLines=0;
 
#endif
Ну и как это работает на примере
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include "classias.h"
 
int main(){
    Menu Main(5,35,5), NewGame(4), Options(3), Keyboard(5), About(1), Score(2);
 
    Main.lineInit(0,&NewGame,      "NEW GAME");
    Main.lineInit(1,&Options,      "OPTIONS");
    Main.lineInit(2,&About,        "ABOUT");
    Main.lineInit(3,&Score,        "SCORE");
    Main.lineInit(4,0,             "EXIT");
 
    NewGame.lineInit(0,&NewGame,   "EASY");
    NewGame.lineInit(1,&NewGame,   "MEDIUM");
    NewGame.lineInit(2,&NewGame,   "HARD");
    NewGame.lineInit(3,&Main,      "BACK");
 
    Options.lineInit(1,&Keyboard,  "KEYBOARD");
    Keyboard.lineInit(4,&Options,  "BACK");
    Options.lineInit(2,&Main,      "BACK");
 
    About.lineInit(0,&Main,        "BACK");
 
    Score.lineInit(1,&Main,        "BACK");
 
    Main.startMenu();
    return 0;
}
В этом меню, пока что, можно только "гулять" из директории в директорию (то есть передавать в nextDir указатель на объект Menu)... И вот я запоролся на вроде бы тривиальной задачке, как реализовать переход к какой-нибудь функции и чтоб это было "красиво", в смысле к примеру чтоб можно было сделать так:
C++
1
2
3
4
5
6
7
void func1( ... ){
    /* . . . */
};
 
/* . . . */
 
NewGame.lineInit(0,func1( ... ),   "EASY");
Ну и естественно желательно чтоб это всё также оставалось храниться в структуре LINES_Data.
У меня есть предположения, что это можно реализовать как-то через шаблоны (template), но для этого потребуется "шаблонить" LINES_Data, а значит, при создании объекта этой структуры, нужно заранее указывать типы, но в моём случае получается, что, до инициализации строки меню, ещё неизвестно какой тип будет у объекта структуры. Правда я совсем недавно изучил шаблоны, и может быть многое про них не знаю, к примеру можно ли как-то обойти объявление типов при объявлении объекта... Но главный мой вопрос этой темы я уже оговорил выше

Добавлено через 8 часов 59 минут
Попробовал всячески через шаблоны, только запутался
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
Текущее время: 16:13. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru