Stejně bych to dělal úplně jinak
menu.h :
#include <iostream>
enum ETyp {submenu,polozka,nic};
struct TVyber {
const char *nadpis;
int polozka;
};
struct TMenu_Line {
const char *nadpis;
int cena;
ETyp typ;
union {
TMenu_Line (*submenu)[];
int polozka;
void *nic;
};
};
mygetchar.cpp : https://stackoverflow.com/questions/22028142/read-only-one-char-from-cin
#include <iostream> // cout, cin, streambuf, hex, endl, sgetc, sbumpc
#include <iomanip> // setw, setfill
#include <fstream> // fstream
// These inclusions required to set terminal mode.
#include <termios.h> // struct termios, tcgetattr(), tcsetattr()
#include <stdio.h> // perror(), stderr, stdin, fileno()
using namespace std;
char mygetchar()
{
struct termios t;
struct termios t_saved;
// Set terminal to single character mode.
tcgetattr(fileno(stdin), &t);
t_saved = t;
t.c_lflag &= (~ICANON & ~ECHO);
t.c_cc[VTIME] = 0;
t.c_cc[VMIN] = 1;
if (tcsetattr(fileno(stdin), TCSANOW, &t) < 0) {
perror("Unable to set terminal to single character mode");
return -1;
}
// Read single characters from cin.
std::streambuf *pbuf = cin.rdbuf();
char c;
c = pbuf->sbumpc();
// Restore terminal mode.
if (tcsetattr(fileno(stdin), TCSANOW, &t_saved) < 0) {
perror("Unable to restore terminal mode");
return -1;
}
return c;
}
menu.cpp :
#include "menu.h"
#include "mygetchar.cpp"
const char *clearScr="\033[2J\033[1;1H";
const char *yellow="\033[33,m";
const char *normal="\033[0,m";
#define MENU 0,submenu, submenu:(TMenu_Line (*)[])&(TMenu_Line [])
#define POLOZKA(A,B) (A),polozka, polozka:(B)
#define KONEC nullptr,.cena=0,nic,nic:nullptr
TMenu_Line *Vyber(const char * nadpis, TMenu_Line (*menu)[]) {
while (true) {
std::cout <<clearScr<<nadpis<<'\n';
char maxch='A';
for (int i=0;(*menu)[i].typ != nic; i++) {
maxch=(char)('A'+i);
std::cout <<'\t'<<yellow<<maxch<<normal<<" - "<<(*menu)[i].nadpis;
if ((*menu)[i].typ == submenu) std::cout << " ==> ";
if ((*menu)[i].typ == polozka) std::cout << "\t Cena : "<< (*menu)[i].cena << ",- Kč ";
std::cout <<'\n';
//<<"Účetní položka :"<<(*menu)[i].polozka<<'\n';
};
std::cout <<"Zadejte A.."<<maxch<<" pro výběr, nebo <Esc> pro návrat: ";
char x;
x=mygetchar();
if (x==033) return nullptr;
if ((x>='a') && (x<='z')) x += 'A'-'a';
if ((x<'A') || (x>maxch)) continue;
int i = x-'A';
if ((*menu)[i].typ == polozka) return &((*menu)[i]);
if ((*menu)[i].typ == submenu) {
TMenu_Line *retval=Vyber((*menu)[i].nadpis,(*menu)[i].submenu);
if (retval) return retval;
};
};
};
TMenu_Line menu[] = {
{"Polévky",MENU {
{"Domácí vývar s nudlemi",POLOZKA(20,1001)},
{"Čočková",POLOZKA(30,1002)},
{KONEC}
}
},
{"Předkrmy",MENU {
{"Šunková rolka s křenem", POLOZKA(15,2001)},
{"Topinka s pikantní směsí", POLOZKA(15,2002)},
{KONEC}
}
},
{"Hlavní jídla",MENU {
{"Kuřecí řízek s bramborem",POLOZKA(105,3001)},
{"Svíčková s knedlíkem",POLOZKA(150,3002)},
{"Vepřo knedlo zelo",POLOZKA(145,3003)},
{KONEC}
}
},
{"Deserty", MENU {
{"Zmrzlinový pohár",POLOZKA(50,4001)},
{"Jablečný závin",POLOZKA(45,4002)},
{KONEC}
}
},
{"Nápoje", MENU {
{"Studené", MENU {
{"Sodovka",POLOZKA(5,5001)},
{"Minerální voda",POLOZKA(10,5002)},
{"Jablečný džus",POLOZKA(20,5003)},
{KONEC}
}
},
{"Teplé", MENU {
{"Turecká káva",POLOZKA(25,6001)},
{"Černý čaj",POLOZKA(25,6002)},
{KONEC}
}
},
{"Alkoholické", MENU {
{"Rum",POLOZKA(50,7001)},
{"Pivo",POLOZKA(45,999)},
{KONEC}
}
},
{"Fakt jen pivo",POLOZKA(45,999)},
{KONEC}
}
},
{"Prostě jen pivo",POLOZKA(45,999)},
{KONEC}
};
int main(int argc,char *argv[]) {
TMenu_Line *vyber = Vyber("*** Vítejte v naší restauraci! ***\nVyberte prosím z následující nabídky: ",(TMenu_Line (*)[])&menu);
if (vyber) {
std::cout <<clearScr <<"Produkt : "<<vyber->nadpis<<'\n'<<"Cena: "<<vyber->cena<<",- Kč\nÚčetní položka : "<<yellow<<vyber->polozka<<normal<<'\n';
return 0;
} else {
std::cout <<clearScr<<"Host si nevybral nic :(\n";
return 1;
};
}