Translated by Leemeans

This commit is contained in:
Means Lee 2018-02-06 22:16:38 +08:00
parent 81fab75c75
commit bbbd55bb61
2 changed files with 214 additions and 214 deletions

View File

@ -1,214 +0,0 @@
leemeans translating
Getting Started with ncurses
======
How to use curses to draw to the terminal screen.
While graphical user interfaces are very cool, not every program needs to run with a point-and-click interface. For example, the venerable vi editor ran in plain-text terminals long before the first GUI.
The vi editor is one example of a screen-oriented program that draws in "text" mode, using a library called curses, which provides a set of programming interfaces to manipulate the terminal screen. The curses library originated in BSD UNIX, but Linux systems provide this functionality through the ncurses library.
[For a "blast from the past" on ncurses, see ["ncurses: Portable Screen-Handling for Linux"][1], September 1, 1995, by Eric S. Raymond.]
Creating programs that use curses is actually quite simple. In this article, I show an example program that leverages curses to draw to the terminal screen.
### Sierpinski's Triangle
One simple way to demonstrate a few curses functions is by generating Sierpinski's Triangle. If you aren't familiar with this method to generate Sierpinski's Triangle, here are the rules:
1. Set three points that define a triangle.
2. Randomly select a point anywhere (x,y).
Then:
1. Randomly select one of the triangle's points.
2. Set the new x,y to be the midpoint between the previous x,y and the triangle point.
3. Repeat.
So with those instructions, I wrote this program to draw Sierpinski's Triangle to the terminal screen using the curses functions:
```
1 /* triangle.c */
2
3 #include
4 #include
5
6 #include "getrandom_int.h"
7
8 #define ITERMAX 10000
9
10 int main(void)
11 {
12 long iter;
13 int yi, xi;
14 int y[3], x[3];
15 int index;
16 int maxlines, maxcols;
17
18 /* initialize curses */
19
20 initscr();
21 cbreak();
22 noecho();
23
24 clear();
25
26 /* initialize triangle */
27
28 maxlines = LINES - 1;
29 maxcols = COLS - 1;
30
31 y[0] = 0;
32 x[0] = 0;
33
34 y[1] = maxlines;
35 x[1] = maxcols / 2;
36
37 y[2] = 0;
38 x[2] = maxcols;
39
40 mvaddch(y[0], x[0], '0');
41 mvaddch(y[1], x[1], '1');
42 mvaddch(y[2], x[2], '2');
43
44 /* initialize yi,xi with random values */
45
46 yi = getrandom_int() % maxlines;
47 xi = getrandom_int() % maxcols;
48
49 mvaddch(yi, xi, '.');
50
51 /* iterate the triangle */
52
53 for (iter = 0; iter < ITERMAX; iter++) {
54 index = getrandom_int() % 3;
55
56 yi = (yi + y[index]) / 2;
57 xi = (xi + x[index]) / 2;
58
59 mvaddch(yi, xi, '*');
60 refresh();
61 }
62
63 /* done */
64
65 mvaddstr(maxlines, 0, "Press any key to quit");
66
67 refresh();
68
69 getch();
70 endwin();
71
72 exit(0);
73 }
```
Let me walk through that program by way of explanation. First, the getrandom_int() is my own wrapper to the Linux getrandom() system call, but it's guaranteed to return a positive integer value. Otherwise, you should be able to identify the code lines that initialize and then iterate Sierpinski's Triangle, based on the above rules. Aside from that, let's look at the curses functions I used to draw the triangle on a terminal.
Most curses programs will start with these four instructions. 1) The initscr() function determines the terminal type, including its size and features, and sets up the curses environment based on what the terminal can support. The cbreak() function disables line buffering and sets curses to take one character at a time. The noecho() function tells curses not to echo the input back to the screen, and the clear() function clears the screen:
```
20 initscr();
21 cbreak();
22 noecho();
23
24 clear();
```
The program then sets a few variables to define the three points that define a triangle. Note the use of LINES and COLS here, which were set by initscr(). These values tell the program how many lines and columns exist on the terminal. Screen coordinates start at zero, so the top-left of the screen is row 0, column 0\. The bottom-right of the screen is row LINES - 1, column COLS - 1\. To make this easy to remember, my program sets these values in the variables maxlines and maxcols, respectively.
Two simple methods to draw text on the screen are the addch() and addstr() functions. To put text at a specific screen location, use the related mvaddch() and mvaddstr() functions. My program uses these functions in several places. First, the program draws the three points that define the triangle, labeled "0", "1" and "2":
```
40 mvaddch(y[0], x[0], '0');
41 mvaddch(y[1], x[1], '1');
42 mvaddch(y[2], x[2], '2');
```
To draw the random starting point, the program makes a similar call:
```
49 mvaddch(yi, xi, '.');
```
And to draw each successive point in Sierpinski's Triangle iteration:
```
59 mvaddch(yi, xi, '*');
```
When the program is done, it displays a helpful message at the lower-left corner of the screen (at row maxlines, column 0):
```
65 mvaddstr(maxlines, 0, "Press any key to quit");
```
It's important to note that curses maintains a version of the screen in memory and updates the screen only when you ask it to. This provides greater performance, especially if you want to display a lot of text to the screen. This is because curses can update only those parts of the screen that changed since the last update. To cause curses to update the terminal screen, use the refresh() function.
In my example program, I've chosen to update the screen after "drawing" each successive point in Sierpinski's Triangle. By doing so, users should be able to observe each iteration in the triangle.
Before exiting, I use the getch() function to wait for the user to press a key. Then I call endwin() to exit the curses environment and return the terminal screen to normal control:
```
69 getch();
70 endwin();
```
### Compiling and Sample Output
Now that you have your first sample curses program, it's time to compile and run it. Remember that Linux systems implement the curses functionality via the ncurses library, so you need to link with -lncurses when you compile—for example:
```
$ ls
getrandom_int.c getrandom_int.h triangle.c
$ gcc -Wall -lncurses -o triangle triangle.c getrandom_int.c
```
Running the triangle program on a standard 80x24 terminal is not very interesting. You just can't see much detail in Sierpinski's Triangle at that resolution. If you run a terminal window and set a very small font size, you can see the fractal nature of Sierpinski's Triangle more easily. On my system, the output looks like Figure 1.
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/triangle.png)
Figure 1. Output of the triangle Program
Despite the random nature of the iteration, every run of Sierpinski's Triangle will look pretty much the same. The only difference will be where the first few points are drawn to the screen. In this example, you can see the single dot that starts the triangle, near point 1\. It looks like the program picked point 2 next, and you can see the asterisk halfway between the dot and the "2". And it looks like the program randomly picked point 2 for the next random number, because you can see the asterisk halfway between the first asterisk and the "2". From there, it's impossible to tell how the triangle was drawn, because all of the successive dots fall within the triangle area.
### Starting to Learn ncurses
This program is a simple example of how to use the curses functions to draw characters to the screen. You can do so much more with curses, depending on what you need your program to do. In a follow up article, I will show how to use curses to allow the user to interact with the screen. If you are interested in getting a head start with curses, I encourage you to read Pradeep Padala's ["NCURSES Programming HOWTO"][2], at the Linux Documentation Project.
### About the author
Jim Hall is an advocate for free and open-source software, best known for his work on the FreeDOS Project, and he also focuses on the usability of open-source software. Jim is the Chief Information Officer at Ramsey County, Minn.
--------------------------------------------------------------------------------
via: http://www.linuxjournal.com/content/getting-started-ncurses
作者:[Jim Hall][a]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://www.linuxjournal.com/users/jim-hall
[1]:http://www.linuxjournal.com/article/1124
[2]:http://tldp.org/HOWTO/NCURSES-Programming-HOWTO

View File

@ -0,0 +1,214 @@
ncurses入门指南
======
怎样使用curses来绘制终端屏幕。
虽然图形界面非常酷但是不是所有的程序都需要点击式的界面。例如令人尊敬的vi编辑器在第一个GUI(出现)之前在纯文本终端运行了很久。
vi编辑器是一个在"文本"模式下绘制的面向屏幕程序的例子。它使用了一个叫curses的库。这个库提供了一系列的编程接口来操纵终端屏幕。curses库产生于BSD UNIX但是Linux系统通过ncurses库提供这个功能。
[了解ncurses"过去曾引起的风暴",参见 ["ncurses: Portable Screen-Handling for Linux"][1], September 1, 1995, by Eric S. Raymond.]
使用curses创建程序实际上非常简单。在这个文章中我展示了一个利用curses来在终端屏幕上绘图的示例程序。
### 谢尔宾斯基三角形
简单展示一些curses函数的一个方法是生成谢尔宾斯基三角形。如果你对生成谢尔宾斯基三角形的这种方法不熟悉的话这里是一些(产生谢尔宾斯基三角形的)规则:
1. 设置定义三角形的三个点。
2. 随机选择任意的一个点(x,y)。
然后:
1. 在三角形的顶点中随机选择一个点
2. 将新的x,y设置为先前的x,y和三角顶点的中间点。
3. 重复(上述步骤)。
所以我按照这些指令写了这个程序程序使用curses函数来向终端屏幕绘制谢尔宾斯基三角形
```
1 /* triangle.c */
2
3 #include <curses.h>
4 #include <stdlib.h>
5
6 #include "getrandom_int.h"
7
8 #define ITERMAX 10000
9
10 int main(void)
11 {
12 long iter;
13 int yi, xi;
14 int y[3], x[3];
15 int index;
16 int maxlines, maxcols;
17
18 /* 初始化 curses */
19
20 initscr();
21 cbreak();
22 noecho();
23
24 clear();
25
26 /* 初始化三角形 */
27
28 maxlines = LINES - 1;
29 maxcols = COLS - 1;
30
31 y[0] = 0;
32 x[0] = 0;
33
34 y[1] = maxlines;
35 x[1] = maxcols / 2;
36
37 y[2] = 0;
38 x[2] = maxcols;
39
40 mvaddch(y[0], x[0], '0');
41 mvaddch(y[1], x[1], '1');
42 mvaddch(y[2], x[2], '2');
43
44 /* 将 yi,xi 初始化为随机值 */
45
46 yi = getrandom_int() % maxlines;
47 xi = getrandom_int() % maxcols;
48
49 mvaddch(yi, xi, '.');
50
51 /* 迭代(形成)三角形 */
52
53 for (iter = 0; iter < ITERMAX; iter++) {
54 index = getrandom_int() % 3;
55
56 yi = (yi + y[index]) / 2;
57 xi = (xi + x[index]) / 2;
58
59 mvaddch(yi, xi, '*');
60 refresh();
61 }
62
63 /* 完成 */
64
65 mvaddstr(maxlines, 0, "Press any key to quit");
66
67 refresh();
68
69 getch();
70 endwin();
71
72 exit(0);
73 }
```
让我一边解释一边浏览这个程序。首先getrandom_int()函数是我对Linux系统调用getrandom()的包装器。它保证返回一个正整数(int)值。(译者注getrandom()系统按照字节返回随机值到一个变量中值是随机的不保证正负使用stdlib.h的random()函数可以达到同样的效果) 另外按照上面的规则你应该能够辨认出初始化和迭代谢尔宾斯基三角形的代码。除此之外我们来看看我用来在终端上绘制三角形的curses函数。
大多数curses程序以这四条指令开头。1)initscr()函数获取包括大小和特征在内的终端类型并设置终端支持的curses环境。cbreak()函数禁用行缓冲并设置curses每次只接受一个字符。noecho()函数告诉curses不要把输入回显到屏幕上。而clear()函数清空了屏幕():
```
20 initscr();
21 cbreak();
22 noecho();
23
24 clear();
```
之后程序设置了三个定义三角的顶点。注意这里使用的LINES和COLS它们是由initscr()来设置的。这些值告诉程序在终端的行数和列数。屏幕坐标从0开始所以屏幕左上角是0行0列。屏幕右下角是LINES - 1行COLS - 1列。为了便于记忆我的程序里把这些值分别设为了变量maxlines和maxcols。
在屏幕上绘制文字的两个简单方法是addch()和addstr()函数。也可以使用相关的mvaddch()和mvaddstr()函数可以将字符放到一个特定的屏幕位置。我的程序在很多地方都用到了这些函数。首先程序绘制三个定义三角的点并标记为"0""1"和"2"
```
40 mvaddch(y[0], x[0], '0');
41 mvaddch(y[1], x[1], '1');
42 mvaddch(y[2], x[2], '2');
```
为了绘制任意的一个初始点,程序做了类似的一个调用:
```
49 mvaddch(yi, xi, '.');
```
还有为了在谢尔宾斯基三角形递归中绘制连续的点:
```
59 mvaddch(yi, xi, '*');
```
当程序完成之后,将会在屏幕左下角(在maxlines行,0列)显示一个帮助信息:
```
65 mvaddstr(maxlines, 0, "Press any key to quit");
```
注意curses在内存中维护了一个版本的屏幕并且只有在你要求的时候才会更新这个屏幕这很重要。特别是当你想要向屏幕显示大量的文字的时候这样(程序会有)更好的表现。这是因为curses只能更新在上次更新之后可以被改变的这部分屏幕。想要引得curses更新终端屏幕请使用refresh()函数。
在我的示例程序中,我选择在"绘制"每个谢尔宾斯基三角形中的连续点时更新屏幕。通过这样做,用户可以观察三角形中的每次迭代。(译者注:迭代过程执行太快了,所以其实很难直接看到迭代过程)
在退出之前我使用getch()函数等待用户按下一个键。然后我调用endwin()函数退出curses环境并返回终端程序到一般控制。
```
69 getch();
70 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
```
译注:此处命令行有问题,`-lncurses`选项在我的Ubuntu16.04系统+gcc 4.9.3 环境下,必须放在命令行最后,否则找不到库文件,链接时会出现未定义的引用。
在标准的80x24终端运行这个triangle程序并没什么意思。在那样的分辨率下你不能看见谢尔宾斯基三角形的很多细节。如果你运行终端窗口并设置非常小的字体大小你可以更加容易地看到谢尔宾斯基三角形的不规则性质。在我的系统上输出如图1。
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/triangle.png)
图 1. triangle程序的输出
虽然迭代具有随机性但是每次谢尔宾斯基三角形的运行看起来都会很一致。唯一的不同是最初绘制到屏幕的一些点。在这个例子中你可以看到开创三角形的一个小圆点在点1附近。看起来程序接下来选择了点2然后你可以看到在圆点和"2"之间的星号。并且看起来程序随机选择了点2作为下一个随机数因为你可以看到在第一个星号和"2"之间的星号。从这里开始,就不能继续分辨三角形是怎样被画出来的了,因为所有的连续点都属于三角形区域。
### 开始学习ncurses
这个程序是一个怎样使用curses函数绘制字符到屏幕的简单例子。按照你的程序的需要你可以通过curses做得更多。在下一篇文章中我将会展示怎样使用curses让用户和屏幕交互。如果你对于在curses有一个良好开端有兴趣我支持你去读位于Linux文档中Pradeep Padala的 ["NCURSES Programming HOWTO"][2]
### 关于作者
Jim Hall是一个免费和开源软件的倡议者他最有名的工作是FreeDOS计划也同样致力于开源软件的可用性。Jim是在明尼苏达州的拉姆齐县的首席资讯长。
--------------------------------------------------------------------------------
via: http://www.linuxjournal.com/content/getting-started-ncurses
作者:[Jim Hall][a]
译者:[leemeans](https://github.com/leemeans)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://www.linuxjournal.com/users/jim-hall
[1]:http://www.linuxjournal.com/article/1124
[2]:http://tldp.org/HOWTO/NCURSES-Programming-HOWTO