第五章 终端
来源:互联网 发布:淘宝如何做企业店铺 编辑:程序博客网 时间:2024/06/02 04:04
menu1.c
#include <stdio.h>#include <stdlib.h>char *menu[] = { "a - add new record", "d - delete record", "q - quit", NULL};int getchoice(char *greet, char *choices[]);int main(){ int choice = 0; do { choice = getchoice("Please select an action", menu); printf("You have chosen: %c\n", choice); } while (choice != 'q'); exit(0);}int getchoice(char *greet, char *choices[]){ int chosen = 0; int selected; char **option; do { printf("Choice: %s\n", greet); option = choices; while(*option){ printf("%s\n", *option); option++; } selected = getchar(); option = choices; while(*option){ if(selected == *option[0]){ chosen = 1; break; } option++; } if(!chosen){ printf("Incorrect choice, select again\n"); } } while(!chosen); return selected;}
isatty
#include <unistd.h>int isatty(int fd);
password.c
#include <termios.h>#include <stdio.h>#include <stdlib.h>#define PASSWORD_LEN 8int main(){ struct termios initialrsetting, newrsetting; char password[PASSWORD_LEN]; tcgetattr(fileno(stdin), &initialrsetting); newrsetting = initialrsetting; newrsetting.c_flag &= ~ECHO; printf("Enter password: "); if(tcsetattr(fileno(stdin), TCSAFLUSH, &newrsetting) != 0) fprintf(stderr, "Could not set attributes\n"); else { fgets(password, PASSWORD_LEN, stdin); tcsetattr(fileno(stdin), TCSANOW, *initialrsetting); fprintf(stdout, "\nYou entered %s\n", password); } exit(0);}
menu3.c:输入输出重定向至/dev/tty
#include <stdio.h>#include <unistd.h>#include <stdlib.h>char *menu[] = { "a - add new record", "d - delete record", "q - quit", NULL};int getchoice(char *greet, char *choices[], FILE *in, FILE *out);int main(){ int choice = 0; FILE *input, *output; 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 opem /dev/tty\n"); exit(1); } do { choice = getchoice("Please select an action", menu, input, output); printf("You have select %c\n", choice); } while(choice != 'q'); exit(0);}int getchoice(char *greet, char *choices[], FILE *in, FILE *out){ int chosen = 0; int selected; char **option; do { fprintf(out, "choice: %s\n",greet); option = choices; while(*option){ fprintf(out, "%s\n", *option); option++; } do { selected = fgetc(in); } while(selected == '\n'); option = choices; while(*option){ if(selected == *option[0]){ fprintf(out, "%s\n", *option); chosen = 1; break; } option++; } if(!chosen) fprintf(out, "Incorrect choice, select again \n"); } while(!chosen); return selected;}
使用terminfo标志
#include <term.h>int setupterm(char *term, int fd, int errret);
- setupterm库函数将当前终端类型设置为参数term所指向的值,如果term是空指针使用环境变量TERM的值
- 参数fd为一个打开的文件描述符,它用于向终端写数据
- 如果errret被设置为空指针,setupterm函数会在失败时输出一条诊断信息并导致程序直接退出
- 如果参数errret不是一个空指针,则函数的返回值保存在该参数指向的的整型变量中,下面给出了可能写入的值:
-1: terminfo数据库不存在
0 : terminfo数据库中没有匹配的数据项
1 : 成功
setupterm..c
#include <stdio.h>#include <term.h>#include <curses.h>#include <stdlib.h>int main(){ setupterm("unlisted", fileno(stdout), (int *)0); printf("Done.\n"); exit(0);}
tigetflag, tigetnum, tigetstr
#include <term.h>int tigetflag(char *capname);int tigetnum(char *capname);char *tigetstr(char *capname);
- tigetflag, tigetnum和tigetstr分别返回terminfo中的布尔功能标志,数值功能标志和字符串功能标志的值.
- 失败时,tigetflag函数返回-1,tigetnum函数返回-2,tigetstr函数返回(char *)-1
- tigetstr函数用来获取xterm终端类型的光标移动功能标志cup的值
sizeterm.c:通过获取terminfo中的cols和lines功能标志来查找当前终端的显示区大小
#include <stdio.h>#include <term.h>#include <curses.h>#include <stdlib.h>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", nrows, ncolumns); exit(0);}
tparm:tparm函数用实际的数值替换功能标志中的参数,一次最多可以替换9个参数,并返回一个可用的escape转义序列
#include <term.h>char *tparm(char *cap, long p1, long p2, ..., long p9);
putp, tputs:将tparm函数构造好的escape转移序列发送给终端,不能使用printf
#include <term.h>int putp(char *const str);int fputs(char *const str, int affect, int (*putfunc)(int));
- putp函数在成功时返回OK, 失败时返回ERR,他以一个终端控制字符串为参数,并将其发送到标准输出stdout
- 如果要将光标移动到屏幕的第5行第30列,可以使用如下代码:
char *cursor;
char *esc_sequence;
cursor = tigetstr("cup");
esc_sequence = tparm(cursor, 5, 30);
putp(esc_sequence); - tputs函数是为不能通过标准输出stdout访问终端的情况准备的,他可以指定一个用于输出字符的函数
- tputs函数的返回值是用户指定的函数putfunc的返回结果
- 参数affcnt的作用是表名受这一行变化影响的行数,他被设置为1
- 真正用于输出控制字符串的函数的参数和返回值类型必须与putchar函数相同
- 事实上,putp(string)就等于tputs(string, 1, putchar)
完整的终端控制:menu5.c
#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <termios.h>#include <term.h>#include <curses.h>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_setting, new_setting; 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_setting); new_setting = initial_setting; new_setting.c_lflag = ~ICANON; new_setting.c_lflag = ~ECHO; new_setting.c_cc[VMIN] = 1; new_setting.c_cc[VTIME] = 0; new_setting.c_lflag = ~ISIG; if(tcsetattr(fileno(input), TCSANOW, &new_setting) != 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); } while(choice != 'q'); tcsetattr(fileno(input), TCSANOW, &initial_settting); exit(0);}int getchoice(char *greet, char *choices[], FILE *in, FILE *out){ int chosen = 0; int selected; int screenrow, secreencol = 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, (int *) 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;}
0 0