Ubuntu下编写终端界面交互式C++小程序的一些Trick(小技巧,gnome-terminal)

类getch()功能的实现

I

只要在Windows下用过C/C++就会很熟悉conio.h库中的一个函数getch(),它可以绕过终端输入缓冲区直接从键盘读取一个字符,并且不在界面上显示。

但如果想直接在Linux环境下用是不行的,因为没有conio.h库的支持。

博主翻了网上的一些资料,在这里给出一个比较简明的实现,使用起来与Windows下没什么差异。

#include<cstdio>
#include<cstdlib>
inline char getch(){
	static char ch;
	system("stty -icanon -echo");
	scanf("%c",&ch);
	system("stty icanon echo");
	return ch;
}

II

不知道大家有没有遇到这样的问题:平时所见的输入语句都需要等待我们输入完才会执行完成,什么都不做的话就会一直阻塞在那里。但我们有时想让程序在尝试接收读入失败的时候能够继续执行下去。这样要怎么实现呢?

我们需要一个函数fcntl,包含在fcntl.h中。使用它可以取消输入阻塞。关于它的更详细的内容可以百度。

我们还需要一个函数read,包含在unistd.h中,是一个底层的输入函数。

定义一个CustomGetch类,包含构造函数、析构函数和运算符()重载,再定义一个该类变量getch,用起来就像函数一样。

#include<cstdlib>
#include<fcntl.h>
#include<unistd.h>
class CustomGetch{
public:
	CustomGetch(){
	    fcntl(0,F_SETFL,O_NONBLOCK);
		system("stty -icanon -echo");
	}
	~CustomGetch(){
		fcntl(0,F_SETFL,0);
		system("stty icanon echo");
	}
	inline char operator()(){
		static char ch;
		return ~read(0,&ch,1)?ch:EOF;
	}
}getch;

这样写有一个局限性:在这个变量的生存周期内,不能和其它的输入方式兼容。因此有两种处理方案:

  1. 在需要getch()而不需要其它输入方式的语句块内定义临时变量。
  2. 直接像I中的那个getch()一样写成函数。但考虑到实际应用中要频繁调用这个函数对输入流进行检查,而system操作相当耗时,所以不推荐这样做。

清屏

因为system("clear")是个假的清屏,所以我们需要更好的实现。

printf("\033c");

对,没了,就一行。

程序示例

#include<cstdio>
#include<cstdlib>
int main(){
	for(int i=0;;++i){
		printf("\033c");
		for(int j=0;j<4;++j)puts(1&i?"abcdefg":"abcbefg");
		system("sleep 1");
	}
	return 0;
}

更改输出起始位置、输出字体颜色

Linux终端有专门的转义字符。看这个博客

posted @ 2019-03-31 23:10  Flash_Hu  阅读(1345)  评论(4编辑  收藏  举报