I've needed to write sample code using conio.h over the years, but my compilers don't support all of it (most notable being clrscr() and gotoxy()). So I wrote a conio simulator class to help me. Not all of the conio.h functions are present, such as cgets() and cscanf(), because I haven't needed them. But the design is such that they can easily be added.
It's based around an abstract IConio class that can be inherited from for specific implementations. The conio.h library is very platform specific, and I've included a Win32 implementation as I work primarily with Windows systems. POSIX implementations aren't especially difficult, but I don't have the confidence in writing something I'd want to show off. ;)
Here's an example program based on one of the samples I wrote recently:
#include <iostream>
#include <string>
#include <Windows.h>
#include "coniolib_win32.h"
namespace {
const console::IConio& conio = console::Win32Conio();
enum {
KEY_ENTER = 13,
KEY_ESC = 27,
KEY_UP = 256 + 72,
KEY_DOWN = 256 + 80,
KEY_LEFT = 256 + 75,
KEY_RIGHT = 256 + 77
};
enum {
HILITE_SELECTED = 433,
HILITE_UNSELECTED = 23
};
int get_key(void)
{
int ch = conio.getch();
if (ch == 0 || ch == 224) {
ch = 256 + conio.getch();
}
return ch;
}
}
int menu(int selected_row = 1)
{
const int size = 3;
const std::string rows[size] = {
"1) Option 1",
"2) Option 2",
"3) Option 3"
};
conio.clrscr();
if (selected_row < 1) {
selected_row = 1;
}
if (selected_row > size) {
selected_row = size;
}
for (int i = 0; i < size; i++) {
if (i + 1 == selected_row) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), HILITE_SELECTED);
}
std::cout << rows[i] << '\n';
if (i + 1 == selected_row) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), HILITE_UNSELECTED);
}
}
std::cout.flush();
return selected_row;
}
void execute_selection(int selection)
{
std::cout << "You selected option " << selection << '\n';
}
int main()
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), HILITE_UNSELECTED);
int selected_row = menu(1);
bool done = false;
while (!done) {
Sleep(100);
if (conio.kbhit()) {
switch (get_key()) {
case KEY_UP:
selected_row = selected_row > 1 ? selected_row - 1 : selected_row;
menu(selected_row);
break;
case KEY_DOWN:
selected_row = selected_row < 3 ? selected_row + 1 : selected_row;
menu(selected_row);
break;
case KEY_ENTER:
execute_selection(selected_row);
break;
case KEY_ESC:
done = true;
break;
default:
break; // Ignore unsupported keys
}
}
}
}