ncurses(또는 curses) 는 Linux/Unix 계열의 환경에서 VT100 등의 터미널과 호환되는 윈도우형 입출력 라이브러이다. 이를 이용하면 윈도우의 임의의 위치에 출력도 하고, 임의의 위치에서 입력을 받을 수도 있다.
다음은 Linux 나 Cygwin 환경이면 gcc 로 컴파일하여 실행되는 C 소스이다.
/*
* Filename: ezmult_003.c
*
* Compile: gcc -o ezmult_003 ezmult_003.c -lform -lncurses
*
* Execute: ./ezmult_003
*
* Date: 2014. 1. 6. (Mon) v0.002
* Date: 2014. 1. 8. (Wed) v0.003
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <form.h>
#include <ncurses.h>
int main()
{
int x0, y0, z0;
int s01, s02, t0;
int x, y, z;
int s1, s2, t;
int i, j;
int flag_insert_mode = 1;
int o1 = 0;
int o2 = 0;
int o3 = 0;
FIELD *field[4];
FORM *my_form;
int ch;
/* curses 초기화하기 */
initscr();
start_color(); // 색상을 사용하려면 initscr() 호출 후 즉시 이를 호출해야 함
nonl(); // 필드에서 엔터 키가 작용되게 하기 위함
cbreak();
noecho();
keypad(stdscr, TRUE);
srand(time(NULL));
x = rand()/(RAND_MAX + 1.0)*90 + 10;
y = rand()/(RAND_MAX + 1.0)*90 + 10;
z = x*y;
s1 = (x/10)*(y/10);
s2 = (x%10)*(y%10);
t = (x/10)*(y%10) + (x%10)*(y/10);
if (s1 < 10)
{
o1 = 1;
}
if (t < 100)
{
o2 = 1;
}
if (z < 1000)
{
o3 = 1;
}
refresh();
/* 필드 초기화 */
field[0] = new_field(1, 4-o1, 6, 14+o1, 0, 0);
field[1] = new_field(1, 3-o2, 7, 14+o2, 0, 0);
field[2] = new_field(1, 4-o3, 9, 14+o3, 0, 0);
field[3] = NULL;
/* 폼 생성하여 붙여 넣기 */
my_form = new_form(field);
post_form(my_form);
refresh();
/* 색상 초기화 */
init_pair(1, COLOR_WHITE, COLOR_GREEN);
init_pair(2, COLOR_WHITE, COLOR_GREEN);
init_pair(3, COLOR_WHITE, COLOR_GREEN);
init_pair(4, COLOR_MAGENTA, COLOR_BLACK);
init_pair(5, COLOR_CYAN, COLOR_BLACK);
init_pair(6, COLOR_WHITE, COLOR_BLACK);
init_pair(7, COLOR_BLACK, COLOR_WHITE);
x0 = rand()/(RAND_MAX + 1.0)*90 + 10;
y0 = rand()/(RAND_MAX + 1.0)*90 + 10;
z0 = x0*y0;
s01 = (x0/10)*(y0/10);
s02 = (x0%10)*(y0%10);
t0 = (x0/10)*(y0%10) + (x0%10)*(y0/10);
mvprintw(3, 4, "%4d", x0);
mvprintw(4, 3, "x%4d", y0);
mvprintw(5, 3, "-----");
mvprintw(6, 4, "%2d%02d", s01, s02);
mvprintw(7, 4, "%3d", t0);
mvprintw(8, 3, "-----");
mvprintw(9, 4, "%4d", z0);
refresh();
mvprintw(3, 14, "%4d", x);
mvprintw(4, 13, "x%4d", y);
mvprintw(5, 13, "-----");
mvprintw(8, 13, "-----");
attron(COLOR_PAIR(7));
mvprintw(0, 0, "Ins");
attron(COLOR_PAIR(6));
move(6, 14);
refresh();
set_field_type(field[0], TYPE_INTEGER, 0, 0, 9999);
set_field_type(field[1], TYPE_INTEGER, 0, 0, 999);
set_field_type(field[2], TYPE_INTEGER, 0, 0, 9999);
field_opts_on(field[0], O_EDIT);
field_opts_on(field[1], O_EDIT);
field_opts_on(field[2], O_EDIT);
field_opts_on(field[0], O_ACTIVE);
field_opts_on(field[1], O_ACTIVE);
field_opts_on(field[2], O_ACTIVE);
/* 필드 옵션 설정 */
set_field_back(field[0], A_UNDERLINE);
set_field_back(field[1], A_UNDERLINE);
set_field_back(field[2], A_UNDERLINE);
/* 필드 옵션 설정 */
set_field_fore(field[0], COLOR_PAIR(1));
set_field_back(field[0], COLOR_PAIR(2));
set_field_fore(field[1], COLOR_PAIR(1));
set_field_back(field[1], COLOR_PAIR(2));
set_field_fore(field[2], COLOR_PAIR(1));
set_field_back(field[2], COLOR_PAIR(2));
if (s1 >= 10)
move(6, 14);
else
move(6, 15);
refresh();
/* 사용자 요구에 따라 번복 여부 결정 */
while((ch = getch()) != KEY_F(1) && ch != 0x1B && ch != 0x0D)
switch(ch)
{
case KEY_DOWN:
case KEY_ENTER:
/* 다음 필드로 가기 */
form_driver(my_form, REQ_NEXT_FIELD);
break;
case KEY_UP:
/* 이전 필드로 가기 */
form_driver(my_form, REQ_PREV_FIELD);
break;
case KEY_BACKSPACE:
case 0x7F:
form_driver(my_form, REQ_DEL_PREV);
break;
case KEY_IC:
if (flag_insert_mode != 0)
{
form_driver(my_form, REQ_OVL_MODE);
getyx(stdscr, j, i);
mvprintw(0, 0, " ");
move(j, i);
flag_insert_mode = 0;
}
else
{
form_driver(my_form, REQ_INS_MODE);
getyx(stdscr, j, i);
attron(COLOR_PAIR(7));
mvprintw(0, 0, "Ins");
attron(COLOR_PAIR(6));
move(j, i);
flag_insert_mode = 1;
}
break;
case KEY_DC:
form_driver(my_form, REQ_DEL_CHAR);
break;
case KEY_LEFT:
form_driver(my_form, REQ_LEFT_CHAR);
break;
case KEY_RIGHT:
form_driver(my_form, REQ_RIGHT_CHAR);
break;
default:
form_driver(my_form, ch);
break;
}
}
form_driver(my_form, REQ_NEXT_FIELD);
attron(COLOR_PAIR(6));
mvprintw(13, 0, "You have answered");
if (atoi(field_buffer(field[0], 0)) == s1*100 + s2)
attron(COLOR_PAIR(5));
else
attron(COLOR_PAIR(4));
mvprintw(14, 8, "%4d", atoi(field_buffer(field[0], 0)));
if (atoi(field_buffer(field[1], 0)) == t)
attron(COLOR_PAIR(5));
else
attron(COLOR_PAIR(4));
mvprintw(15, 8, "%3d", atoi(field_buffer(field[1], 0)));
if (atoi(field_buffer(field[2], 0)) == z)
attron(COLOR_PAIR(5));
else
attron(COLOR_PAIR(4));
mvprintw(16, 8, "%4d", atoi(field_buffer(field[2], 0)));
attron(COLOR_PAIR(6));
mvprintw(13, 20, "Right answer is");
mvprintw(14, 28, "%2d%02d", s1, s2);
mvprintw(15, 28, "%3d", t);
mvprintw(16, 28, "%4d", z);
if (atoi(field_buffer(field[0], 0)) == s1*100 + s2
&& atoi(field_buffer(field[1], 0)) == t
&& atoi(field_buffer(field[2], 0)) == z)
mvprintw(18, 0, " Your answer is right.");
else
mvprintw(18, 0, " Your answer is wrong.");
mvprintw(21, 0, "Press any key to quit...");
getch();
/* 폼을 떼어내고 메모리를 해제한다. */
unpost_form(my_form);
free_form(my_form);
free_field(field[0]);
free_field(field[1]);
free_field(field[2]);
endwin();
return 0;
}
* 실행 결과:
'프로그래밍 > C' 카테고리의 다른 글
cygwin/mingw 의 gcc 로 utf-8 한글 처리하기 (0) | 2014.04.02 |
---|---|
Visual C++ 2010 과 pdcurses 를 이용한 helloworld 예제 (0) | 2014.01.15 |
64bit 리눅스에서 32bit 용 C 소스 컴파일하기 (0) | 2014.01.04 |
오일러(Euler) phi 함수 구현하기 (0) | 2013.12.14 |
long long 타입의 정수를 printf 함수로 출력하기 (0) | 2013.12.03 |