通过termios结构体我们可以控制输入,但是我们也希望能够控制输出
1.终端的类型
终端有很多种,再计算机发展早期,不同厂家制造的终端设备不一样,但是后面有了一定的标准,通过命令 echo $TERM 可以查看自己的终端类型
终端有一个终端软件包,里面定义了终端的各种属性
我们可以查看终端的各种属性,比如查看vt100的终端:infocmp vt100
Reconstructed via infocmp from file: /usr/share/terminfo/v/vt100
vt100|vt100-am|dec vt100 (w/advanced video),
am, mc5i, msgr, xenl, xon,
cols#80, it#8, lines#24, vt#3,
acsc=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
bel=^G, blink=\E[5m$<2>, bold=\E[1m$<2>,
clear=\E[H\E[J$<50>, cr=^M, csr=\E[%i%p1%d;%p2%dr,
cub=\E[%p1%dD, cub1=^H, cud=\E[%p1%dB, cud1=^J,
cuf=\E[%p1%dC, cuf1=\E[C$<2>,
cup=\E[%i%p1%d;%p2%dH$<5>, cuu=\E[%p1%dA,
cuu1=\E[A$<2>, ed=\E[J$<50>, el=\E[K$<3>, el1=\E[1K$<3>,
enacs=\E(B\E)0, home=\E[H, ht=^I, hts=\EH, ind=^J, ka1=\EOq,
ka3=\EOs, kb2=\EOr, kbs=^H, kc1=\EOp, kc3=\EOn, kcub1=\EOD,
kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA, kent=\EOM, kf0=\EOy,
kf1=\EOP, kf10=\EOx, kf2=\EOQ, kf3=\EOR, kf4=\EOS, kf5=\EOt,
kf6=\EOu, kf7=\EOv, kf8=\EOl, kf9=\EOw, lf1=pf1, lf2=pf2,
lf3=pf3, lf4=pf4, mc0=\E[0i, mc4=\E[4i, mc5=\E[5i, rc=\E8,
rev=\E[7m$<2>, ri=\EM$<5>, rmacs=^O, rmam=\E[?7l,
rmkx=\E[?1l\E>, rmso=\E[m$<2>, rmul=\E[m$<2>,
rs2=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h, sc=\E7,
sgr=\E[0%?%p1%p6%|%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m%?%p9%t\016%e\017%;$<2>,
sgr0=\E[m\017$<2>, smacs=^N, smam=\E[?7h, smkx=\E[?1h\E=,
smso=\E[7m$<2>, smul=\E[4m$<2>, tbc=\E[3
上面定义了很多东西,比如每次显示多少行和多少列,
2.使用terminfo功能标志
#include<term.h>
(1)获取终端类型:这个函数会初始化TERMINAL结构,后续的操作都是基于这个初始化
setupterm(char* term, int fd, int* errret);
将当前终点设置为term所指向的值,如果term是空指针,就是用环境变量TERM的值,
fd是文件描述符,它用于向终端写数据
errret保存返回值。
(2)获取terminfo的功能标志
a)int tigetflag(char* capname) 布尔功能标志
b)int tigetnum(char* capname) 数值功能标志
c)char* tigetstr(char* capname) 字符串功能标志
比如获取终端的大小
#include<term.h>
#include<stdio.h>
#include<curses.h>
int main()
{
int nrows, ncolumns;
setupterm(NULL, fileno(stdout), (int*)0);//获取各种变量
nrows = tigetnum("lines");//获取行
ncolumns = tigetnum("lines");//获取行
if(nrows < 0 || ncolumns < 0)
{
fprintf(stderr,"获取失败\n");
return 0;
}
printf("row = %d column = %d\n",nrows,ncolumns);
return 0;
}
(3).char* tparm(char* cap, long p1,long p2,..., long p9)用实际的数值替换功能标志的参数,一次最多可以替换9个,并且返回一个escape转义序列
获取到转义序列之后,需要发送出去给终端,下面两个函数可以实现这个过程
int putp(char* const str);
int tputs(char* const str, int affcnt, int (*putfunc)(int))
比如将光标移动到第5行30列
#include<term.h>
#include<stdio.h>
#include<curses.h>
int main()
{
int nrows, ncolumns;
setupterm(NULL, fileno(stdout), (int*)0);//获取各种变量
char* cursor = NULL;
char* esc_sequence = NULL;
cursor = tigetstr("cup");
if(cursor == NULL)
{
fprintf(stderr,"获取光标属性失败\n");
return 0;
}
//设置
esc_sequence = tparm(cursor,5,30);
if(esc_sequence == NULL)
{
fprintf(stderr,"设置失败\n");
return 0;
}
putp(esc_sequence);
return 0;
}