简介

本文介绍了命令行弹幕云实现。会不定期更新。

工具准备-ncurses

工欲善其事,必先利其器。在网上了解了一番类似nano的实现之后,将编程语言瞄准了C。在C语言小游戏—命令行飞船大战中找到了可能实现的细节,但由于上述程序运行于win,在关于Linux下光标定位的问题!!!中找到答案ncurses

在上述网页中,有NCURSES Programming HOWTO。于是开始学习。

坑-第一个用例无法实现

对于我这种初学者,第一个用例就无法正常跑起来。

1
echo "^[[0;31;40mIn Color"

它显示了文字^[[0;31;40mIn Color。解决的办法很简单,见How to printf() with colors? [solved]。其实在文中也有提到这个问题。使用press CTRL+V and then the ESC key来打出^[,而非复制粘贴。

which looks like two characters ^ and [.To be able to print it, you have to press CTRL+V and then the ESC key

ncurses首接触-Hello world

安装ncurses后,开始首个用例。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#include <ncurses.h>

int main()
{	
	initscr();			/* Start curses mode 		  */
	printw("Hello World !!!");	/* Print Hello World		  */
	refresh();			/* Print it on to the real screen */
	getch();			/* Wait for user input */
	endwin();			/* End curses mode		  */

	return 0;
}
  • initscr(); 开始光标模式
  • refresh(); 输出缓冲区到屏幕
  • endwin(); 结束光标模式

程序比较简单,此处不展开叙述,详细解读点

ncurses初始化功能

在初始化中,有许多好用的功能,见下例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <ncurses.h>

int main()
{	int ch;

	initscr();			/* Start curses mode 		*/
	raw();				/* Line buffering disabled	*/
	keypad(stdscr, TRUE);		/* We get F1, F2 etc..		*/
	noecho();			/* Don't echo() while we do getch */

    	printw("Type any character to see it in bold\n");
	ch = getch();			/* If raw() hadn't been called
					 * we have to press enter before it
					 * gets to the program 		*/
	if(ch == KEY_F(1))		/* Without keypad enabled this will */
		printw("F1 Key pressed");/*  not get to us either	*/
					/* Without noecho() some ugly escape
					 * charachters might have been printed
					 * on screen			*/
	else
	{	printw("The pressed key is ");
		attron(A_BOLD);
		printw("%c", ch);
		attroff(A_BOLD);
	}
	refresh();			/* Print it on to the real screen */
    getch();			/* Wait for user input */
	endwin();			/* End curses mode		  */

	return 0;
}
  • stdscr 默认窗口
  • raw(); 获取原始输入
  • keypad(stdscr, TRUE); 捕获F类按键
  • noecho(); 不显示输入的字符

程序比较简单,此处不展开叙述,详细解读点

ncurses的多种打印方式

ncurses的3种打印方式,addch()printw()addstr()

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include <ncurses.h>			/* ncurses.h includes stdio.h */  
#include <string.h> 
 
int main()
{
    char mesg[]="Just a string";		/* message to be appeared on the screen */
    int row,col;				/* to store the number of rows and *
                        * the number of colums of the screen */
    initscr();				/* start the curses mode */
    getmaxyx(stdscr,row,col);		/* get the number of rows and columns */
    mvprintw(row/2,(col-strlen(mesg))/2,"%s",mesg);
                                    /* print the message at the center of the screen */
    mvprintw(row-2,0,"This screen has %d rows and %d columns\n",row,col);
    printw("Try resizing your window(if possible) and then run this program again");
    refresh();
    getch();
    endwin();

    return 0;
}
  • addch类
    • addch(ch); 输出单字符
    • mvaddch(row,col,ch); 到某坐标后输出单字符
    • waddch(WINDOW *win, chtype ch); 到某窗口输出单字符
    • mvwaddch(WINDOW *win, int y, int x, chtype ch); 到某窗口、某坐标后输出单字符
  • printw类
    • printw() 输出格式化字符串
    • mvprintw() 到某坐标后输出格式化字符串
    • wprintw() 到某窗口输出格式化字符串
    • mvwprintw() 到某窗口、某坐标后输出格式化字符串
    • vwprintw() 到某窗口输出格式化字符串(数组输入)
  • addstr类
    • addstr() 等同对字符串每个字符调用addch
    • mvaddstr() 同上类似
    • waddstr() 同上类似
    • mvwaddstr() 同上类似

程序比较简单,此处不展开叙述,详细解读点

ncurses的多种输入方式

ncurses有3种输入方式,getch()获取一个字符,scanw()getstr()获取直到EOF的字符串。

  • scanw类
    • scanw() 格式化输入
    • mvscanw() 到某位置后格式化输入
    • wscanw() 到某窗口后格式化输入
    • mvwscanw() 同上类似
    • vwscanw() 同上类似
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include <ncurses.h>			/* ncurses.h includes stdio.h */  
#include <string.h> 
 
int main()
{
    char mesg[]="Enter a string: ";		/* message to be appeared on the screen */
    char str[80];
    int row,col;				/* to store the number of rows and *
                        * the number of colums of the screen */
    initscr();				/* start the curses mode */
    getmaxyx(stdscr,row,col);		/* get the number of rows and columns */
    mvprintw(row/2,(col-strlen(mesg))/2,"%s",mesg);
                            /* print the message at the center of the screen */
    getstr(str);
    mvprintw(LINES - 2, 0, "You Entered: %s", str);
    getch();
    endwin();

    return 0;
}

程序比较简单,此处不展开叙述,详细解读点

ncurses输出装饰

下面列出一些常用的装饰属性。多属性使用|并。

    A_NORMAL        标准 Normal display (no highlight)
    A_STANDOUT      突出 Best highlighting mode of the terminal.
    A_UNDERLINE     下划 Underlining
    A_REVERSE       翻转 Reverse video
    A_BLINK         闪烁 Blinking
    A_DIM           半亮 Half bright
    A_BOLD          超亮 Extra bright or bold
    A_PROTECT       保护 Protected mode
    A_INVIS         隐藏 Invisible or blank mode
    A_ALTCHARSET    备用 Alternate character set
    A_CHARTEXT      Bit-mask to extract a character
    COLOR_PAIR(n)   颜色 Color-pair number n 

下面列出一些常见功能

  • attron() 打开某些装饰
  • attroff() 关闭某些装饰
  • attrset() 设置为某些装饰
  • standend() 清除装饰
  • attr_get() 获取装饰
  • attr_前置 基本同上
  • w前置 针对特定窗口

*chgat(int n, attr_t attr, short color, const void opts)

  • n 为应用的字符数量,为-1时到行尾为止。
  • const 总为NULL

chgat在设置装饰时不会移动光标位置。有wmvmvw前缀,意义同上。

一个chgat的例子。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <ncurses.h>

int main(int argc, char *argv[])
{	initscr();			/* Start curses mode 		*/
	start_color();			/* Start color functionality	*/
	
	init_pair(1, COLOR_CYAN, COLOR_BLACK);
	printw("A Big string which i didn't care to type fully ");
	mvchgat(0, 0, -1, A_BLINK, 1, NULL);	
	/* 
	 * First two parameters specify the position at which to start 
	 * Third parameter number of characters to update. -1 means till 
	 * end of line
	 * Forth parameter is the normal attribute you wanted to give 
	 * to the charcter
	 * Fifth is the color index. It is the index given during init_pair()
	 * use 0 if you didn't want color
	 * Sixth one is always NULL 
	 */
	refresh();
    getch();
	endwin();			/* End curses mode		  */
	return 0;
}

程序比较简单,此处不展开叙述,详细解读点

ncurses的窗口