Chinaunix首页 | 论坛 | 博客
  • 博客访问: 19912509
  • 博文数量: 679
  • 博客积分: 10495
  • 博客等级: 上将
  • 技术积分: 9308
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-18 10:51
文章分类

全部博文(679)

文章存档

2012年(5)

2011年(38)

2010年(86)

2009年(145)

2008年(170)

2007年(165)

2006年(89)

分类: LINUX

2008-12-11 11:07:43

§5.5  终端输出

       Printf不能在屏幕的指定位置输出。

 

     终端类型

 

ANSIVT100, VT220, or ANSI等类型。

Terminfo包,curses等专门处理这些东东。

 

Terminfo需要curses.hterm.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));

 

比如移动到第530列。

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;

}

 

阅读(4385) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~