分类: LINUX
2008-12-11 11:07:43
Printf不能在屏幕的指定位置输出。
*
终端类型
有ANSI,VT100, VT220, or ANSI等类型。
Terminfo包,curses等专门处理这些东东。
Terminfo需要curses.h,term.h.支持,一些linux还需要ncurses.h。
*
确定终端类型
Linux中有$TERM
# echo $TERM
Linux
Terminfo的描述信息一般存储在/usr/lib/terminfo or /usr/share/terminfo,比如/usr/share/terminfo/v/vt100。
Terminfo文件需要使用tic命令等制作,制作过程暂略。
以下暂略
*
使用terminfo能力
安装终端使用setupterm,它会初始化一个TERMINAL结构。
#include
int setupterm(char *term, int fd, int *errret);
函数说明:
The setupterm
library function sets
the current terminal type to that specified by the parameter term.
If term
is a null pointer,
the TERM environment variable will be used. An open file descriptor to be used
for
writing to the terminal must be passed as fd. The function outcome is stored in the
integer variable
pointed
to by errret, if this isn’t a null pointer. The value written will be
❑ –1: No terminfo
database
❑ 0: No matching entry in terminfo
database
❑ 1: Success
The setupterm
function returns the
constant OK if it succeeds and ERR if it fails. If errret is set to a null
pointer,
setupterm will print a diagnostic message and exit the program if it fails, as in
this example:
错误调用的实例:
vi badterm.c
#include
#include
#include
#include
int main()
{
setupterm("unlisted", fileno(stdout), (int *)0);
printf("Done.\n");
exit(0);
}
# gcc -o badterm badterm.c -lncurses
[root@localhost chapter05]# ./badterm
'unlisted': unknown terminal type.
[root@localhost chapter05]# vi badterm.c
#include
#include
#include
#include
int main()
{
setupterm("vt100", fileno(stdout), (int *)0);
printf("Done.\n");
exit(0);
}
# gcc -o badterm badterm.c -lncurses
[root@localhost chapter05]# ./badterm
Done.
访问终端属性:
#include
int tigetflag(char *capname);
int tigetnum(char *capname);
char *tigetstr(char *capname);
函数说明:The functions tigetflag, tigetnum, and tigetstr
return the value of
Boolean, numeric, and string
terminfo capabilities, respectively. On failure (for example, if
the capability isn’t present), tigetflag
returns
-1, tigetnum returns -2, and tigetstr returns (char *)-1.
You
can use the terminfo database to find out the size of the terminal by retrieving the cols
and lines
capabilities
with this program, sizeterm.c:
# cat sizeterm.c
#include
#include
#include
#include
int main()
{
int nrows,
ncolumns;
setupterm(NULL,
fileno(stdout), (int *)0);
nrows =
tigetnum("lines");
ncolumns =
tigetnum("cols");
printf("This terminal has %d columns and %d rows\n", ncolumns,
nrows);
exit(0);
}
# gcc -o sizeterm sizeterm.c -lncurses
[root@localhost chapter05]# ./sizeterm
This terminal has 125 columns and 40 rows
光标定位:
#include
char *tparm(char *cap, long p1, long p2, ..., long p9);
然后输出
#include
int putp(char *const str);
int tputs(char *const str, int affcnt, int
(*putfunc)(int));
比如移动到第5行30列。
char *cursor;
char *esc_sequence;
cursor = tigetstr(“cup”);
esc_sequence = tparm(cursor,5,30);
putp(esc_sequence);
函数说明
The tputs function is provided for those situations when
the terminal isn’t accessed via stdout and
allows you to specify the function to be used for
outputting the characters. It returns the result of the userspecified
function putfunc. The affcnt parameter is intended to
indicate the number of lines affected by
the change. It’s normally set to 1. The function used to
output the string must have the same parameters
and return type as the putchar function. Indeed, putp(string)
is equivalent to the call tputs(string,
1, putchar). You’ll see tputs used with a user-specified
output function in the next example
清屏的方法见教材。
菜单实例:蓝色部分是与menu4.c的区别
# cat menu5.c
#include
#include
#include
#include
#include
#include
static FILE *output_stream = (FILE *)0;
char *menu[] = {
"a - add
new record",
"d -
delete record",
"q -
quit",
NULL,
};
int getchoice(char *greet, char *choices[], FILE *in,
FILE *out);
int char_to_terminal(int char_to_write);
int main()
{
int choice = 0;
FILE *input;
FILE *output;
struct termios
initial_settings, new_settings;
if
(!isatty(fileno(stdout))) {
fprintf(stderr,"You are not a terminal, OK.\n");
}
input =
fopen("/dev/tty", "r");
output =
fopen("/dev/tty", "w");
if(!input ||
!output) {
fprintf(stderr, "Unable to open /dev/tty\n");
exit(1);
}
tcgetattr(fileno(input),&initial_settings);
new_settings =
initial_settings;
new_settings.c_lflag &= ~ICANON;
new_settings.c_lflag &= ~ECHO;
new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VTIME] = 0;
new_settings.c_lflag &= ~ISIG;
if(tcsetattr(fileno(input), TCSANOW, &new_settings) != 0) {
fprintf(stderr,"could not set attributes\n");
}
do {
choice =
getchoice("Please select an action", menu, input, output);
printf("You have chosen: %c\n", choice);
sleep(1);
} while (choice
!= 'q');
tcsetattr(fileno(input),TCSANOW,&initial_settings);
exit(0);
}
int getchoice(char *greet, char *choices[],
FILE *in, FILE *out)
{
int
chosen = 0;
int
selected;
int
screenrow, screencol = 10;
char
**option;
char
*cursor, *clear;
output_stream = out;
setupterm(NULL,fileno(out), (int *)0);
cursor = tigetstr("cup");
clear = tigetstr("clear");
screenrow = 4;
tputs(clear, 1, char_to_terminal);
tputs(tparm(cursor, screenrow, screencol), 1, char_to_terminal);
fprintf(out, "Choice: %s", greet);
screenrow += 2;
option = choices;
while(*option) {
tputs(tparm(cursor, screenrow, screencol), 1, char_to_terminal);
fprintf(out,"%s", *option);
screenrow++;
option++;
}
fprintf(out, "\n");
do {
fflush(out);
selected = fgetc(in);
option = choices;
while(*option) {
if(selected == *option[0]) {
chosen = 1;
break;
}
option++;
}
if(!chosen) {
tputs(tparm(cursor, screenrow, screencol), 1, char_to_terminal);
fprintf(out,"Incorrect choice, select again\n");
}
}
while(!chosen);
tputs(clear, 1, char_to_terminal);
return selected;
}
int char_to_terminal(int char_to_write)
{
if
(output_stream) putc(char_to_write, output_stream);
return 0;
}