当前位置: 技术问答>linux和unix
linux终端编程的一些小问题,希望得到解答!
来源: 互联网 发布时间:2017-05-24
本文导语: 大家好,最近开始着手学习linux程序设计这本书,看到第五章终端输出的时候对那个terminfo的工作机制不是很了解,希望请教一下如下几个问题: 1:tpus函数的工作原理是什么?函数原型是: int tputs(char *const str,int af...
大家好,最近开始着手学习linux程序设计这本书,看到第五章终端输出的时候对那个terminfo的工作机制不是很了解,希望请教一下如下几个问题:
1:tpus函数的工作原理是什么?函数原型是:
int tputs(char *const str,int affcnt, int (*putfunc) (int));
我的理解是str指向的字符串的值传递给用户指定的putfunc这个函数,让这个函数对其进行处理。不知理解的是否到位?
2:程序段中clear获取的是功能标志clear中的值,然后调用tputs函数再传递给char_to_terminal函数进行屏幕的清屏处理,请问为何将clear中的值传递给char_to_terminal函数进行putc输出流就可以清屏?是否因为clear中已经由系统设置好了一系列的转义字符,从而我们可以使用这些转义字符进行控制?
3:关于tputs函数中参数affcnt,书上的解释是受这一函数变化影响的行数,请问这个行数是一个什么样子的概念?
对以上问题本菜鸟不是很清楚,下面的程序段我做了一系列的注释,不知道对这块理解的是否到位?因为是初学linux编程没多久,所以对某些概念依旧模糊不清,希望各位前辈能够不吝赐教,指点一二!谢谢!
1:tpus函数的工作原理是什么?函数原型是:
int tputs(char *const str,int affcnt, int (*putfunc) (int));
我的理解是str指向的字符串的值传递给用户指定的putfunc这个函数,让这个函数对其进行处理。不知理解的是否到位?
2:程序段中clear获取的是功能标志clear中的值,然后调用tputs函数再传递给char_to_terminal函数进行屏幕的清屏处理,请问为何将clear中的值传递给char_to_terminal函数进行putc输出流就可以清屏?是否因为clear中已经由系统设置好了一系列的转义字符,从而我们可以使用这些转义字符进行控制?
3:关于tputs函数中参数affcnt,书上的解释是受这一函数变化影响的行数,请问这个行数是一个什么样子的概念?
对以上问题本菜鸟不是很清楚,下面的程序段我做了一系列的注释,不知道对这块理解的是否到位?因为是初学linux编程没多久,所以对某些概念依旧模糊不清,希望各位前辈能够不吝赐教,指点一二!谢谢!
#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; //定义两个termios结构,initial存放默认的终端接口变量的值,new存放新的终端接口变量的值
if (!isatty(fileno(stdout))) { //使用fileno获取当前终端的文件描述符,并且用isatty函数进行判断是否为一个终端
fprintf(stderr,"You are not a terminal, OK.n");
}
input = fopen("/dev/tty", "r"); //以只读方式打开/dev/tty设备,并且把文件流赋值给input
output = fopen("/dev/tty", "w"); //同上
if(!input || !output) {
fprintf(stderr, "Unable to open /dev/ttyn");
exit(1);
}
tcgetattr(fileno(input),&initial_settings); //把当前终端接口变量的值存放到initial参数指向的结构中去
new_settings = initial_settings; //初始化新的一个termios的结构变量,用下面的标志位进行设置新的值
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) { //用tcsetattr设置好最新的终端设置如果失败则输出提示信息
fprintf(stderr,"could not set attributesn");
}
do {
choice = getchoice("Please select an action", menu, input, output); //进行选择
printf("You have chosen: %cn", 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; //用output_stream存放输出流
setupterm(NULL,fileno(out), (int *)0); //将当前终端类型设置为参数term指向的值,因为此时term是空指针,就使用环境变量term的值
cursor = tigetstr("cup"); //返回当前terminfo中字符串变量cup的值
clear = tigetstr("clear"); //同上
screenrow = 4; //设置横边为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控制,就不许要换行符了。
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 againn");
}
} 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;
}
|
这个没涉及过,回答不了