ncurses - C++ code reduction for identical submenus -


i coding way last project of semester , have code duplication issue. using ncurses or pdcurses make menu interact user.

the problem: each choice of menu(five in total) need submenu. submenu's difference main menu is, array of items printed, , parameters go functions, result of items array size. since need 5 submenus, need 5 times same code(six if add main menu).

could of me make function same thing, i'll call 6 times create menu?

here's code

void menu(){     const char* items[]={         "[1]...new tax declaration",         "[2]...modify tax declaration",         "[3]...cancel tax declaration",         "[4]...additional information",         "[5]...exit"     };     int cur=0;     int ch, i;     int flag=0;     do{         werase(wm);         mvwaddstr(wm, 2, 16, "menu");         for(int i=0; i<5;i++){             if(i==cur)                 wattr_on(wm, a_reverse, 0);             mvwaddstr(wm, 4+i, 4, items[i]);             wattr_off(wm, a_reverse, 0);         }         mvwaddstr(wm, 14, 3, "choice: ");         wprintw(wm, "%1d", cur+1);         wrefresh(wm);         ch=wgetch(wm);         switch(ch){             case '1':cur=0;sub2();break;             case '2':cur=1;sub1();break;             case '3':cur=2;break;             case '4':cur=3;break;             case '5':flag=1;break;             case key_up:             case key_left: cur--; if (cur<0) cur=4; break;             case key_down:             case key_right: cur++; if(cur>4) cur=0; break;             case 27: flag=1; break;             case 32:             case 13:                 switch (cur){                     case 0:sub2();break;                     case 1:sub1();break;                     case 2:break;                     case 3:break;                     case 4:flag=1;break;                 }         }     }while(!flag); } 

thank you.

p.s code book. have little experience ncurses, don't hard on me :p. want final project code better :).

a simple menu-driven program. based on using std::map instead of conditional logic. map stores list of menuitem structures define menu looks , each option does.

this best explained work through code, let's dive in!

// headers used in example #include <iostream> #include <string> #include <map> #include <functional> #include <cctype>  // function perform menu option b sub option 1 void optionb1() {     std::cout << "perfoming b1" << std::endl; }  // function perform menu option b sub option 2 void optionb2() {     std::cout << "perfoming b2" << std::endl; }  // function perform menu option void optiona() {     std::cout << "perfoming a" << std::endl; }  // defines menu item. naming can save need comment struct menuitem  {     std::function<void()> doit; // function run if option chosen     std::string description; // pretty message describing option };  // draw menu , wait user select option. void domenu(const std::map<char, menuitem> & menu) {     while (true) // loop until user gives option. or use retry count.                   // decide.     {         (auto &items : menu)         { // items in menu, print out item , it's description text           // first , second mean, read on std::map , std::pair             std::cout << items.first << ") " << items.second.description << std::endl;         }         char ch;         std::cin >> ch; // user's choice         // may want eliminate 1 of cases reduce amount          // of possible inputs need provide handling code for.         // line below allows use same code input of , a.         ch = std::tolower(ch); // convert input lower case         try         {             menu.at(ch).doit(); // call function mapped user's choice.                                 // may produce or may                                 // display menu. end wor--             return; // done.         }         catch (...)         { // print error message on unsupported input             std::cout << "error. invalid option!" << std::endl;         }     } }   // b menu std::map<char, menuitem> bmenu { // user input  doit function      description     {'1',       {optionb1,          "option b1"}},     {'2',       {optionb2,          "option b2"}}     // add more options here. or don't. you. };  // main menu std::map<char, menuitem> mainmenu { // user input  doit function              description     {'a',       {optiona,                   "option a"}},     {'b',       {std::bind(domenu, bmenu),  "option b"}}     // ok, last 1 bit weird. std::bind makes function ,     // specifies arguments called. takes     // domenu binds bmenu std::function<void()>     // satisfied. far world concerned, bound function     // returns nothing , takes no parameters. complicated functions      // can bound long end result returns nothing , requires      // no parameters.      // it's doing here allowing call domenu draw b      // submenu, wait valid input, , call chosen function. };  // 'ol trusty main can test above code isn't utter bs. int main() {     while (true) // loop forever. or use whatever exit logic required.     {         domenu(mainmenu); // kick-start calling menu run main menu     }     return(0); } 

this keep code down minimum. of duplicated code reduced domenu function , smurfload of code hidden sight in standard library , written folks have far more experience in getting stuff right or i. whenever possible, stand on shoulders of giants.

domenu driven lists of options , execution instructions option. want option? add item list , possibly provide new function fulfill obligations of option.

all have fill in blanks.


Popular posts from this blog

php - How should I create my API for mobile applications (Needs Authentication) -

5 Reasons to Blog Anonymously (and 5 Reasons Not To)

Google AdWords and AdSense - A Dynamic Small Business Marketing Duo