[转帖]ncurses 入门指南

ncurses,入门,指南 · 浏览次数 : 0

小编点评

**代码示例:** ```c #include int main() { // 初始化 ncurses 库 initscr(); // 设置屏幕大小 y = 0; x = 0; // 绘制三角形 mvaddch(y[0], x[0], '0'); mvaddch(y[1], x[1], '1'); mvaddch(y[2], x[2], '2'); // 绘制三角形中的点 mvaddch(yi, xi, '*'); // 显示帮助信息 mvaddstr(maxlines, 0, "Press any key to quit\n"); // 等待用户输入 getch(); // 退出 ncurses 环境 endwin(); return 0; } ``` **代码功能:** 1. 初始化 ncurses 库。 2. 设置屏幕大小。 3. 绘制三角形顶点。 4. 绘制三角形中的点。 5. 显示帮助信息。 6. 等待用户输入。 7. 退出 ncurses 环境。 **输出:** ``` Press any key to quit ``` **解释:** 程序首先初始化了 ncurses 库,然后设置了屏幕大小。然后,它绘制了三角形顶点和三角形中的点。最后,它显示了帮助信息。 **注意:** 程序的输出会随着三角形迭代的变化而改变。在最初的迭代中,三角形顶点位于屏幕左上角,而最终的迭代中,它位于屏幕左下角。这是因为程序随机选择下一个随机数来绘制三角形中的点。

正文

https://www.imooc.com/article/80504

 

 

怎样使用 curses 来绘制终端屏幕?

 

虽然图形界面非常酷,但是不是所有的程序都需要点击式的界面。例如,令人尊敬的 Vi 编辑器在第一个 GUI 出现之前在纯文本终端运行了很久。

 

Vi 编辑器是一个在“文本”模式下绘制的面向屏幕screen-oriented程序的例子。它使用了一个叫 curses 的库。这个库提供了一系列的编程接口来操纵终端屏幕。curses 库产生于 BSD UNIX,但是 Linux 系统通过 ncurses 库提供这个功能。

 

[要了解 ncurses “过去曾引起的风暴”,参见 ncurses: Portable Screen-Handling for Linux, September 1, 1995, by Eric S. Raymond.]

 

使用 curses 创建程序实际上非常简单。在这个文章中,我展示了一个利用 curses 来在终端屏幕上绘图的示例程序。

 

谢尔宾斯基三角形

简单展示一些 curses 函数的一个方法是生成谢尔宾斯基三角形Sierpinski's Triangle。如果你对生成谢尔宾斯基三角形的这种方法不熟悉的话,这里是一些产生谢尔宾斯基三角形的规则:

 

设置定义三角形的三个点。

随机选择任意的一个点 (x,y)。

然后:

 

在三角形的顶点中随机选择一个点。

将新的 x,y 设置为先前的 x,y 和三角顶点的中间点。

重复(上述步骤)。

所以我按照这些指令写了这个程序,程序使用 curses 函数来向终端屏幕绘制谢尔宾斯基三角形:

 

/* triangle.c */

#include <curses.h>

#include <stdlib.h>

#include "getrandom_int.h"

#define ITERMAX 10000

int main(void)

{

  long iter;

  int yi, xi;

  int y[3], x[3];

  int index;

  int maxlines, maxcols;

  /* initialize curses */

  initscr();

  cbreak();

  noecho();

  clear();

  /* initialize triangle */

  maxlines = LINES - 1;

  maxcols = COLS - 1;

  y[0] = 0;

  x[0] = 0;

  y[1] = maxlines;

  x[1] = maxcols / 2;

  y[2] = 0;

  x[2] = maxcols;

  mvaddch(y[0], x[0], '0');

  mvaddch(y[1], x[1], '1');

  mvaddch(y[2], x[2], '2');

  /* initialize yi,xi with random values */

  yi = getrandom_int() % maxlines;

  xi = getrandom_int() % maxcols;

  mvaddch(yi, xi, '.');

  /* iterate the triangle */

  for (iter = 0; iter < ITERMAX; iter++) {

      index = getrandom_int() % 3;

      yi = (yi + y[index]) / 2;

      xi = (xi + x[index]) / 2;

      mvaddch(yi, xi, '*');

      refresh();

  }

  /* done */

  mvaddstr(maxlines, 0, "Press any key to quit");

  refresh();

  getch();

  endwin();

  exit(0);

}

让我一边解释一边浏览这个程序。首先,getrandom_int() 函数是我对 Linux 系统调用 getrandom() 的包装器。它保证返回一个正整数(int)值。(LCTT 译注:getrandom() 系统调用按照字节返回随机值到一个变量中,值是随机的,不保证正负,使用 stdlib.h 的 random() 函数可以达到同样的效果)另外,按照上面的规则,你应该能够辨认出初始化和迭代谢尔宾斯基三角形的代码。除此之外,我们来看看我用来在终端上绘制三角形的 curses 函数。

 

大多数 curses 程序以这四条指令开头。 initscr() 函数获取包括大小和特征在内的终端类型,并设置终端支持的 curses 环境。cbreak() 函数禁用行缓冲并设置 curses 每次只接受一个字符。noecho() 函数告诉 curses 不要把输入回显到屏幕上。而 clear() 函数清空了屏幕:

 

  initscr();

  cbreak();

  noecho();

  clear();

之后程序设置了三个定义三角的顶点。注意这里使用的 LINES 和 COLS,它们是由 initscr() 来设置的。这些值告诉程序在终端的行数和列数。屏幕坐标从 0 开始,所以屏幕左上角是 0 行 0 列。屏幕右下角是 LINES - 1 行,COLS - 1 列。为了便于记忆,我的程序里把这些值分别设为了变量 maxlines 和 maxcols。

 

在屏幕上绘制文字的两个简单方法是 addch() 和 addstr() 函数。也可以使用相关的 mvaddch() 和 mvaddstr() 函数可以将字符放到一个特定的屏幕位置。我的程序在很多地方都用到了这些函数。首先程序绘制三个定义三角的点并标记为 '0','1' 和 '2':

 

  mvaddch(y[0], x[0], '0');

  mvaddch(y[1], x[1], '1');

  mvaddch(y[2], x[2], '2');

为了绘制任意的一个初始点,程序做了类似的一个调用:

 

  mvaddch(yi, xi, '.');

还有为了在谢尔宾斯基三角形递归中绘制连续的点:

 

      mvaddch(yi, xi, '*');

当程序完成之后,将会在屏幕左下角(在 maxlines 行,0 列)显示一个帮助信息:

 

  mvaddstr(maxlines, 0, "Press any key to quit");

注意 curses 在内存中维护了一个版本的屏幕显示,并且只有在你要求的时候才会更新这个屏幕,这很重要。特别是当你想要向屏幕显示大量的文字的时候,这样程序会有更好的性能表现。这是因为 curses 只能更新在上次更新之后改变的这部分屏幕。想要让 curses 更新终端屏幕,请使用 refresh() 函数。

 

在我的示例程序中,我选择在“绘制”每个谢尔宾斯基三角形中的连续点时更新屏幕。通过这样做,用户可以观察三角形中的每次迭代。(LCTT 译注:由于 CPU 太快,迭代过程执行就太快了,所以其实很难直接看到迭代过程)

 

在退出之前,我使用 getch() 函数等待用户按下一个键。然后我调用 endwin() 函数退出 curses 环境并返回终端程序到一般控制。

 

  getch();

  endwin();

编译和示例输出

现在你已经有了你的第一个 curses 示例程序,是时候编译运行它了。记住 Linux 操作系统通过 ncurses 库来实现 curses 功能,所以你需要在编译的时候通过 -lncurses来链接——例如:

 

$ ls

getrandom_int.c  getrandom_int.h  triangle.c

$ gcc -Wall -lncurses -o triangle triangle.c getrandom_int.c

(LCTT 译注:此处命令行有问题,-lncurses 选项在我的 Ubuntu 16.04 系统 + gcc 4.9.3 环境下,必须放在命令行最后,否则找不到库文件,链接时会出现未定义的引用。)

 

在标准的 80x24 终端运行这个 triangle 程序并没什么意思。在那样的分辨率下你不能看见谢尔宾斯基三角形的很多细节。如果你运行终端窗口并设置非常小的字体大小,你可以更加容易地看到谢尔宾斯基三角形的不规则性质。在我的系统上,输出如图 1。

图 1. triangle 程序的输出

图 1. triangle 程序的输出

虽然迭代具有随机性,但是每次谢尔宾斯基三角形的运行看起来都会很一致。唯一的不同是最初绘制到屏幕的一些点的位置不同。在这个例子中,你可以看到三角形开始的一个小圆点,在点 1 附近。看起来程序接下来选择了点 2,然后你可以看到在圆点和“2”之间的星号。并且看起来程序随机选择了点 2 作为下一个随机数,因为你可以看到在第一个星号和“2”之间的星号。从这里开始,就不能继续分辨三角形是怎样被画出来的了,因为所有的连续点都属于三角形区域。

 

开始学习 ncurses

这个程序是一个怎样使用 curses 函数绘制字符到屏幕的简单例子。按照你的程序的需要,你可以通过 curses 做得更多。在下一篇文章中,我将会展示怎样使用 curses 让用户和屏幕交互。

编译自:http://www.linuxjournal.com/content/getting-started-ncurses作者: Jim Hall
原创:LCTT https://linux.cn/article-9348-1.html译者: leemeans

与[转帖]ncurses 入门指南相似的内容:

[转帖]ncurses 入门指南

https://www.imooc.com/article/80504 怎样使用 curses 来绘制终端屏幕? 虽然图形界面非常酷,但是不是所有的程序都需要点击式的界面。例如,令人尊敬的 Vi 编辑器在第一个 GUI 出现之前在纯文本终端运行了很久。 Vi 编辑器是一个在“文本”模式下绘制的面向屏

[转帖]Linux中iptraf命令详解

https://www.sohu.com/a/217620611_610671 iptraf是一个基于ncurses开发的IP局域网监控工具,它可以实时地监视网卡流量,可以生成各种网络统计数据,包括TCP信息、UDP统计、ICMP和OSPF信息、以太网负载信息、节点统计、IP校验和错误和其它一些信息

[转帖]Linux 流量监控工具:iptraf-ng 的安装与使用

环境 Linux/Ubuntu 18.04 + 安装iptraf-ng-1.2.1,可编译安装,安装包链接:iptraf-ng-1.2.1.zip 解压iptraf-ng-1.2.1 unzip ./iptraf-ng-1.2.1.zip 安装ncurses(系统是ubuntu18.04) sudo

[转帖]

Linux ubuntu20.04 网络配置(图文教程) 因为我是刚装好的最小系统,所以很多东西都没有,在开始配置之前需要做下准备 环境准备 系统:ubuntu20.04网卡:双网卡 网卡一:供连接互联网使用网卡二:供连接内网使用(看情况,如果一张网卡足够,没必要做第二张网卡) 工具: net-to

[转帖]

https://cloud.tencent.com/developer/article/2168105?areaSource=104001.13&traceId=zcVNsKTUApF9rNJSkcCbB 前言 Redis作为高性能的内存数据库,在大数据量的情况下也会遇到性能瓶颈,日常开发中只有时刻

[转帖]ISV 、OSV、 SIG 概念

ISV 、OSV、 SIG 概念 2022-10-14 12:29530原创大杂烩 本文链接:https://www.cndba.cn/dave/article/108699 1. ISV: Independent Software Vendors “独立软件开发商”,特指专门从事软件的开发、生产、

[转帖]Redis 7 参数 修改 说明

2022-06-16 14:491800原创Redis 本文链接:https://www.cndba.cn/dave/article/108066 在之前的博客我们介绍了Redis 7 的安装和配置,如下: Linux 7.8 平台 Redis 7 安装并配置开机自启动 操作手册https://ww

[转帖]HTTPS中间人攻击原理

https://www.zhihu.com/people/bei-ji-85/posts 背景 前一段时间,公司北京地区上线了一个HTTPS防火墙,用来监听HTTPS流量。防火墙上线之前,邮件通知给管理层,我从我老大那里听说这个事情的时候,说这个有风险,然后意外地发现,很多人原来都不知道HTTPS防

[转帖]关于字节序(大小端)的一点想法

https://www.zhihu.com/people/bei-ji-85/posts 今天在一个技术群里有人问起来了,当时有一些讨论(不完全都是我个人的观点),整理一下: 为什么网络字节序(多数情况下)是大端? 早年设备的缓存很小,先接收高字节能快速的判断报文信息:包长度(需要准备多大缓存)、地

[转帖]awk提取某一行某一列的数据

https://www.jianshu.com/p/dbcb7fe2da56 1、提取文件中第1列数据 awk '{print $1}' filename > out.txt 2、提取前2列的文件 awk `{print $1,$2}' filename > out.txt 3、打印完第一列,然后打