Almost all the programmers or every Computer science student in the wild would have practiced C programming, some might have just memorized few programs for the sake of exams. But still, those who really gained the knowledge to write C programs would have missed out all the interesting concepts of C, and Curses is one of them, available on all Linux and Unix variants. You can run Curses with Cygwin for Windows. Now after years of development and with new features added it is called as Ncurses ( New Curses ). Developed in early 1980 to manage application’s display on character-cell terminals.
Programming with NCurses will be lot more interesting because of the formatted output, but it is lot more than that. It aims at providing a library of advanced functions that can be used to develop wonderful applications with “GUI like” interface with C. You can control every input including keyboard and mouse, as well as the output.
Creating menu with Ncurses in C.
Though Ncurses has a special include directive “menu.h” for creating beautiful and flexible menus, in this article I am not going to use it, we will create a menu with basic Ncurses functions. But before going into the program we will see how Ncurses handles the rows and columns of the terminal screen.
The above image shows how curses library maps the screen into rows and columns. ( As always programmers count form zero. ). With this basic understanding let’s go into the code.
Simple menu Programs with NCURSES
#include<ncurses.h> main() { WINDOW *w; char list[5][7] = { "One", "Two", "Three", "Four", "Five" }; char item[7]; int ch, i = 0, width = 7; initscr(); // initialize Ncurses w = newwin( 10, 12, 1, 1 ); // create a new window box( w, 0, 0 ); // sets default borders for the window // now print all the menu items and highlight the first one for( i=0; i<5; i++ ) { if( i == 0 ) wattron( w, A_STANDOUT ); // highlights the first item. else wattroff( w, A_STANDOUT ); sprintf(item, "%-7s", list[i]); mvwprintw( w, i+1, 2, "%s", item ); } wrefresh( w ); // update the terminal screen i = 0; noecho(); // disable echoing of characters on the screen keypad( w, TRUE ); // enable keyboard input for the window. curs_set( 0 ); // hide the default screen cursor. // get the input while(( ch = wgetch(w)) != 'q'){ // right pad with spaces to make the items appear with even width. sprintf(item, "%-7s", list[i]); mvwprintw( w, i+1, 2, "%s", item ); // use a variable to increment or decrement the value based on the input. switch( ch ) { case KEY_UP: i--; i = ( i<0 ) ? 4 : i; break; case KEY_DOWN: i++; i = ( i>4 ) ? 0 : i; break; } // now highlight the next item in the list. wattron( w, A_STANDOUT ); sprintf(item, "%-7s", list[i]); mvwprintw( w, i+1, 2, "%s", item); wattroff( w, A_STANDOUT ); } delwin( w ); endwin(); }
The above sample code will draw a box with menu items printed and the first menu item highlighted. And will wait for the user input, upon pressing the up and down arrow keys you can navigate the menu. Here is the code break-down and instruction on how to run a C program with Ncurses library.
First we should include the ncurses.h header to use the Ncurses functions – #include <ncurses.h>, then within the program we should start with initscr() function which initializes NCurses. Many say that it clears the terminal screen, but it actually sets up the internal memory structures and input/output interfaces between the NCurses functions and your computer’s terminal.
Then we create a new window, with the newwin() function. This function has to be given four co-ordinates which is rows, cols, y_orgin, and x_orgin respectively.
Then the call to box() function defines a window border clearly, so that you can have make it standout on your terminal screen, also know that, this just draws border, which is prone to overwriting and accidental erasing.
After creating the window we print all the menu items one below the other and highlight the first item. For high-lighting the text we use wattron() function, with A_STANDOUT attribute, few more high-lighting modes are available for which you can refer the Ncurses manual page.
Then we disable echo and enable keypad to capture the special keys and navigate the menu. We are also using sprintf to right pad the string with spaces to display them with even width.
Compiling and linking Ncurses programs
You should compile Ncurses programs by linking it to Ncurses library like this.
gcc program.c -lncurses
The above program will give you the following output, You can also expand it to the most advanced menu or bar menu or as you wish. Happy coding!!
Creating Menu with Curses Menu Library in C
I appreciate your sharing of the example, but have you looked at how it’s been formatted and displayed?
It looks like minified JavaScript, not the well-commented C that you had probably intended.
Thank you, I have fixed it now, pls check and let me know.
Thanks for this snippet! Have thrown menu.h away and now i’m using your code.
But i think it should be “char item[8];” instead of “char item[7];” because “sprintf(item, “%-7s”, list[i]);” will write 8 bytes (fixed 7 bytes and 1 zero) and not 7 bytes.
Thanks a lot for the appreciation and for pointing out the mistake.
But Menus (menu.h) is much more powerful, you can create selectable (with multi select) and scrollable menus