Dividing the terminal
I am doing a quiz in c for project. I can manage most of the code but the basic thing is i want my output screen(the terminal) to be divided into sections 1 for instructions,others for timer and score the score will be incremented/decremented according to users reply but i want it to be printed in the score box constantly, like throughout the program instru,timer and score should be visible in upper half and lower half i want to change the questions? how can i divide this terminal so?:confused:
I will have to download the ncurses.h library for this right?Isn't there any other simpler way?
That depends on what you mean by simpler. It's not that hard to download and install ncurses. If you haven't done such a thing before, it's good practice. It's not the "ncurses.h" library. That's just the header file. It also comes with the actual library which contains the compiled object code (or you can get the source code and compile it yourself).
What OS are you using? If it's windows, then you can look into the Console Functions
If you don't mind a quick and dirty approach, you could also try this: Create a 2D character array that will contain everything to be displayed on your "screen." Then just update the appropriate indices and re-print the whole array.
// load array with values
// print entire array
// 1 +-----------+
// 2 | SCORE: 16 |
// 3 +-----------+
For extra fun, use the extended ASCII codes to create "frames" around your data, if supported by your system.
// update score to 24
screen = '2';
screen = '4';
// print entire array again
// 1 +-----------+
// 2 | SCORE: 24 |
// 3 +-----------+
I just realized what a stupid question this is on a Linux forum!
Originally Posted by oogabooga
Matticus has a good idea for a "simpler" approach.
Why do people ask if there is a simple way to do something that is obviously not simple?
Originally Posted by kulkarnipooja
Laziness. That's why there's, as one example, "Learn to Play Guitar In One Day!" videos. It takes many years to hone demanding skills, but many people simply aren't interested in the journey to take them to the desired destination.
 Did I just answer a rhetorical question? =)
Since you are using Linux, you can use ANSI escape codes to control your output. You simply add control sequences to your outputs to clear the screen, clear the end of the line, move to a specific row or column, and so on. The CSI mentioned in the link above is just the string "\033[".
At the start of your program, you'll want to clear the terminal window. For example,
Note that since there is no newline at the end of the string we just printed, the C library is likely to cache it. To make sure it is actually emitted, you need to call fflush(stdout); . I won't show it in the following examples, but you need to remember to call it at the point you wish to have all changes actually visible.
When you wish to refresh the screen, you redraw everything. To avoid flashing, you don't clear the screen, just move to the upper left corner,
Then, you print the contents of each line. You can either use an array, or a helper function. The important point is that instead of just printing a newline, you print clear the end of this line followed by a newline:
After you have printed everything you want, you clear the rest of the screen using
You can move to any row and column (both start at 1) using
Some other useful codes:
printf("\033[%d;%dH", row, column);
I've listed the available color codes here.
printf("\033[?25l"); /* Hide cursor */
printf("\033[?25h"); /* Show cursor */
printf("\033[s"); /* Save current cursor position */
printf("\033[u"); /* Restore cursor position */
Portability note: These codes work on basically everywhere that has a color-capable command line terminal, except current Windows systems. For details, see the ISO/IEC 6429 and ECMA-48 standards, which describe these. For some reason, Microsoft decided to omit the support from the cmd.exe shell; it used to provide optional support for command.com in ANSI.SYS.
Based on Nominal Animals posts, I've managed to put together some cheesey macros for ANSI control sequences. They're a bit rough. I plan on spending more time with it and fleshing them out a bit. But here's a first draft for anyone that might find them useful.
NOTE: I borrowed the listing of ANSI Color codes from a post by Nominal Animal. He should get most of the credit for the codes in this header I've created.
If you find them useful, then great... if not, then perhaps some suggestions?
* Some ansi control character sequence macros by Twiki
* CREDITS: Special thanks to Nominal Animal and Wikipedia for explaining ANSI control codes
* and a special thanks again to Nominal Animal, without whom this collection of ANSI macros
* would not be possible.
* DATE: Thursday, November 15th 2012
* LICENSE: Public Domain (MMXII)
* Make sure we're compiling on a UNIX or workalike operating system
* One of these symbols should be defined somewhere either internally by the compiler
* or in the common includes typical of a c program... tested on OpenBSD and Debian Linux
* I'm not aware of a compiler system for any *NIX variant in which one of these aren't defined
#if !(defined(unix) || defined(_unix) || defined(__unix) || defined(__unix__) || defined(_unix_) \
|| defined(UNIX) || defined(_UNIX) || defined(__UNIX) || defined(__UNIX__) || defined(_UNIX_))
#error "The macros in ansi.h require a unix or workalike operating system to function properly!"
/* NOTE: The following color values come from a listing posted on cboard by the user Nominal Animal
* I've copied them here to complete my ansi.h header which I intend to post on cboard for the purpose
* of providing others a simple set of macros to use in order to manipulate color ansi terminal displays
* All credit for the following color values goes to Nominal Animal without whom, this collection of macros
* would not be possible.
/* Uses Web color names, see http://en.wikipedia.org/wiki/Web_colors */
#define ALL_NORMAL "\033[0m"
#define FG_BLACK "\033[22;30m"
#define FG_MAROON "\033[22;31m" /* Dark red */
#define FG_GREEN "\033[22;32m"
#define FG_OLIVE "\033[22;33m" /* Brown */
#define FG_NAVY "\033[22;34m" /* Dark blue */
#define FG_PURPLE "\033[22;35m"
#define FG_TEAL "\033[22;36m" /* Dark cyan */
#define FG_SILVER "\033[22;37m" /* Light gray */
#define FG_GRAY "\033[1;30m" /* Dark gray */
#define FG_RED "\033[1;31m" /* Light red */
#define FG_LIME "\033[1;32m" /* Light green */
#define FG_YELLOW "\033[1;33m"
#define FG_BLUE "\033[1;34m"
#define FG_FUCHSIA "\033[1;35m" /* Light purple */
#define FG_AQUA "\033[1;36m" /* Light cyan */
#define FG_WHITE "\033[1;37m"
#define BG_BLACK "\033[40m"
#define BG_MAROON "\033[41m"
#define BG_GREEN "\033[42m"
#define BG_OLIVE "\033[43m"
#define BG_NAVY "\033[44m"
#define BG_PURPLE "\033[45m"
#define BG_TEAL "\033[46m"
#define BG_SILVER "\033[47m"
/* NOTE: Credit for the following macros goes to Nominal Animal, without whom these macros would not
* be possible. Many of them come directly from Nominal Animal's posts on cboard
* All of these macros do the same thing... They set the cursor position to the x and y coordinates
* Where x is the column, and y is the row
#define SETCURPOS(x,y) printf("\033[%d;%dH",y,x)
#define SETXY(x,y) printf("\033[%d;%dH",y,x)
#define XY(x,y) printf("\033[%d;%dH",y,x)
#define GOTOXY(x,y) printf("\033[%d;%dH",y,x)
* Moves the cursor up count lines
#define CURUP(count) printf("\033[%dA",count)
* Moves the cursor down count lines
#define CURDOWN(count) printf("\033[%dB",count)
* Move the cursor forward by count cells
#define INCCUR(count) printf("\033[%dC",count)
* Move cursor backward by count cells
#define DECCUR(count) printf("\033[%dD", count)
* Decrement cursor n lines up
#define DECLINE(n) printf("\033[%dE",n)
* Increment cursor n lines down
#define INCLINE(n) printf("\033[%dF",n)
* Set the current cursor column ( x coordinate ) position to n
#define SETCOLUMN(n) printf("\033[%dG")
#define SETX(n) printf("\033[%dG")
* Takes no arguments... Hides the cursor
#define HIDECUR() printf("\033[?25l")
* Takes no arguments... Shows a previously hidden cursor
#define SHOWCUR() printf("\033[?25h")
* Takes no arguments... Saves the cursor position internally
#define SAVECURPOS() printf("\033[s")
* Takes no arguments... Restores a previously saved cursor position
#define RESTORECURPOS() printf("\033[u")
* Takes no arguments... Resets the cursor position to the top left of the screen
#define RESETCUR() printf("\033[H")
* All three of these macros do the same thing... They clear the screen
* They don't take any arguments
#define CLEARSCR() printf("\033[H\033[2J"); fflush(stdout)
#define CLS() printf("\033[H\033[2J"); fflush(stdout)
#define CLEAR() printf("\033[H\033[2J"); fflush(stdout)
* Clear from cursor position to end of screen
#define CLEARTOEOS() printf("\033[0J")
#define CLEOS() printf("\033[0J")
* Clear from cursor to beginning of screen
#define CLEARTOBOS() printf("\033[1J")
#define CLBOS() printf("\033[1J")
* Clear the entire contents of the current line
#define CLEARLINE() printf("\033[2K")
#define CLN() printf("\033[2K")
* Clear from cursor position to end of line
#define CLEARTOEOL() printf("\033[0K")
#define CLEOL() printf("\033[0K")
* Clear from cursor position to beginning of line
#define CLEARTOBOL() printf("\033[1K")
#define CLBOL() printf("\033[1K")
* Sets the foreground text color to "color" specified. "color" must be a string literal containing the
* appropriate foreground ANSI color code for the desired color. Above are a listing of FG_XXXX color
* literals defined to make things easier on the user. e.g. SETFG(FG_GREEN) sets the text color to dark green.
#define SETFG(color) printf("%s",color)
* Sets the background text color to "color" specified. "color" must be a string literal containing the
* appropriate background ANSI color code for the desired color. Above are a listing of BG_XXXX color
* literals defined to make things easier on the user. e.g. SETBG(FG_NAVY) sets the background color to navy blue.
#define SETBG(color) printf("%s",color)
* Sets the foreground and background color to fg (foreground) and bg (background) colors specified. fg and bg must
* be a string literal containing the appropriate foreground and background ANSI color codes for the desired colors.
* Above are a listing of FG_XXXX and BG_XXXX color literals defined to make things easier on the user.
* e.g. SETCOLOR(FG_WHITE,BG_NAVY) sets the foreground color to white and the background color to Navy Blue
#define SETCOLOR(fg,bg) printf("%s%s",fg,bg)
* Scrolls the screen up by n lines.
#define SCROLLUP(n) printf("\033[%dS",n)
* Scrolls the screen down by n lines
#define SCROLLDOWN(n) printf("\033[%dT",n)
#define SCRDOWN(n) printf("\033[%dT",n)
#define SCRDWN(n) printf("\033[%dT",n)
/* __ANSI_H__ */
Cool macros - handy for some light-weight CLIs. However I would still recommend you check out ncurses if you ever do anything like this again. As mentioned above, if you're unable to install and use that library, learning to do so will give you some very crucial Linux / C programming skills and is probably simpler than you think. Ncurses also makes it easier to handle much more complicated interactions with the terminal and deals with any inconsistencies between different terminals/emulators that you might come across. These macros seem simple to you now, but if you do much more interaction they will quickly become more complicated to maintain than just using nurses.
Yeah. ncurses is probably the best option. These macros are definitely limited. I've actually got a slightly improved version of this header which should compile on non-unix targets.
Originally Posted by sean
One limitation I've already encountered is not being able to determine the terminal dimensions which makes more advanced use of these macros very difficult to say the least...
And as you mentioned, there's the differences in implementations among ANSI terminal emulators.
NOTE: One macro which I didn't include in this version which is an absolute must is the following... For anyone using my macros, be sure to add the following to your copy
You'll want to call that macro after setting any colors to restore the terminal defaults ( seems to work )
* Reset all attributes to the default
#define RESET() printf("\033[0m")
#define RESTORE() printf("\033[0m")