GNU-ncurses库简介

14 篇文章 0 订阅


前言

ncurses是一个管理应用程序在字符终端显示的函数库。它提供了移动光标,建立窗口,产生颜色,处理鼠标操作等功能。
ncurses提供的是字符用户界面,而非图形用户界面。


一、安装与使用

在Ubuntu下执行如下命令

sudo apt-get install libncurses5-dev

在编译时需要加上-lncurses选项

在运行编译好的二进制文件时也要安装ncurses库

二、ncurses库基本用法

#include <ncurses.h>

int main()
{
    initscr();  // 初始化,进入ncurses模式,创建虚拟屏幕
    printw("hello world");  // 在虚拟屏幕上光标位置打印 hello world
    refresh();  // 将虚拟屏幕上的内容写到显示器上,并刷新
    getchar();  // libc
    endwin();   // 推出ncurses模式
}

2.1 initscr()

将终端屏幕初始化为curses模式,该函数初始化了curses系统并且为当前屏幕(“stdscr”)和相关的数据结构分配内存。

2.2 refresh()

printw函数用于向stdscr虚拟屏幕缓冲区写入数据,refresh函数负责将stdscr缓冲区中的数据显示在屏幕上。refresh只核查窗口和数据中变动的部分。

2.3 endwin()

释放了curses子系统和相关数据结构占用的内存,使得能够正常返回控制台模式,否则程序推出后终端显示会变得异常。

三、初始化

初始化后curses session的模式及功能包括:terminal mode, color mode, mouse mode 等

3.1 raw(), cbreak()

一般而言,终端驱动程序会缓冲用户输入的字符,直到遇到换行符或者回车符后,这些字符才可以被使用。raw和cbreak可以禁止行缓冲(line buffering):row可以处理ctrl+z, ctrl+c等控制字符,将其传送至程序而不产生终端信号;cbreak则不会这样处理.

3.2 echo() noecho()

noecho() 禁止输入的字符出现在屏幕上

3.3 keypad()

为stdscr激活功能键 keypad(stdscr, true)

3.4 int halfdelay(int)

以 0.1 s 为单位等待用户输入,若在规定的时间内没有输入则返回#define ERR -1

#include <unistd.h>
#include <stdio.h>
#include <ncurses.h>

int main()
{
    initscr();   // 开始curses模式
    int ch;
    curs_set(false);  // 关闭光标显示
    raw();  // 禁用输入缓冲
    keypad(stdscr, TRUE);  // 没有它当按下Fn时程序似乎不正常
    noecho();   // 当执行getch函数时关闭键盘回显
    // 向缓冲区stdscr中写数据
    printw("Type any character to seee it in bold\n");
    // 用法同getchar,但又有区别,可尝试换成getchar会怎样
    // curses库中getch与getchar用法相似,但如果用getchar函数会出现的显示上的问题
    // 这个问题有待进一步探究
    ch = getch();  // 如果没有raw()函数必须按下enter时才将字符传给程序
    for (int i = 1; i<=12; ++i) {
    	// 如果没有keypad将不会执行这条语句
        if (ch == KEY_F(i)) {
            printw("F%d Key pressed", i);
            // 如果没有noecho一些控制字符将被打印到屏幕上
            goto conti_exe;
        }
    }
    printw("The pressed key is ");
    attron(A_BOLD);  // 看名知意
    printw("%c", ch);
    attroff(A_BOLD);
    conti_exe:
    refresh();  // 将stdscr的内容显示到屏幕
    getch();    // 等待用户输入
    endwin();  // 结束curses模式

}

四、窗口机制简介

printw(string);  // 在窗口stdscr的当前坐标输出string
refresh();

// w+  指定窗口显示
wprintw(win, string);  // 在win上写string
wrefresh(win);  // 刷新窗口win

// mv+ 在指定位置打印
mvprintw(y, x, string);  在stdscr的(y, x)处写string
mvwprintw(win, y, x, string);  // 在win的(y, x)处写string 

五、输出函数

addch()系列:将单一的字符打印到屏幕上,可以附加字符修饰参数的一类函数
printw()系列:类似printf格式化输出
addstr()系列:打印字符串

addch( ch | A_BOLD | A_UNDERLINE);

attrset(), 不可叠加文本属性
attron(), attroff() 可叠加文本属性

ACS_ 开头的宏可用于绘制一些简单的表格、线条等

vwprintw()和vprintf()相似,用于打印变量表中所对应的变量(没用过)

指定窗口指定位置指定窗口+位置
addchwaddchmvaddchmvwaddch
addstrwaddstrmvaddstrmvwaddstr
printwwprintwmvprintwmvwprintw

getmaxyx

    initscr();
    curs_set(false);
    raw();
    keypad(stdscr, TRUE);
    noecho();
    
    char mesg[] = "Just a string";
    int row, col;
    getmaxyx(stdscr, row, col);
    mvprintw(row/2, (col-strlen(mesg))/2, "%s", mesg);
    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 prog)");

    refresh();
    getch();
    endwin();

六、输入函数

getch() 系列:读取一个字符
scanw()系列:按照格式化读取输入
getstr() 系列:读取字符串

scanwwscanwmvscanwmvwscanw
getchwgetchmvgetchmvwgetch
    char mesg[] = "Just a string";
    char str[80];
    int row, col;
    getmaxyx(stdscr, row, col);
    mvprintw(LINES/2, (COLS-strlen(mesg))/2, "%s", mesg);
    getstr(str);
    mvprintw(LINES-2, 0, "You ENtered:%s\n", str);

    printw("row:%d, col:%d, LINES:%d", row, col, LINES);

七、输出修饰

#include <unistd.h>
#include <stdio.h>
#include <ncurses.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{

    
//
    int ch, prev;
    FILE *fp;
    int goto_prev = false, y, x; /* sdfg*/
    if (argc != 2)
    {
        printf("error");
        exit(1);
    }
    fp = fopen(argv[1], "r");
    if (fp == NULL)
    {
        perror("Connot open inputfile");
        exit(1);
    }

    initscr();
    curs_set(false);
    raw();
    keypad(stdscr, TRUE);
    noecho();


    prev = EOF;
    while ((ch = fgetc(fp)) != EOF)
    {
        if (prev == '/' && ch == '*')
        {
            attron(A_BOLD);
            goto_prev = true;
        }
        if (goto_prev == true)
        {
            getyx(stdscr, y, x);
            move(y, x -1);
            printw("%c%c", '/', ch);
            ch = 'a';
            goto_prev = false;
        }
        else
        {
            printw("%c", ch);
        }
        refresh();
        if (prev == '*' && ch == '/')
        {
            attroff(A_BOLD);
        }
        prev = ch;
    }
    
    
///
    refresh();
    getch();
    endwin();

}
说明
A_NORMAL普通字符
说明
attrset会覆盖之前的设置
attron会追加
attroff只会关闭特定修饰
standend()等价于attrset(A_NORMAL)
attr_get()获得当前窗口修饰属性设置及背景、文字颜色
需要在设置的修饰之后才能使用
attr_类函数
wattr_类函数
chgat()
wchgat()
mvchgat()
mvwchgat()
    start_color();
    init_pair(1, COLOR_CYAN, COLOR_BLACK);
    printw("A Big string which i didn't care to type fully");
    mvchgat(0, 10, 4, A_BLINK, 1, NULL);
    //  第三个参数表示从光标开始的向后几个字符,-1代表整行, 

八、窗口机制

声明说明
WINDOW * newwin (h, w, y, x);创建窗口结构体
int delwin(WINDOW*);释放窗口资源
int wborder(win, L, R, U, D, 左上, 右上,左下,右下)绘制边框
int mvhline(y, x, char, num)draw h line
int mvvline(y, x, char, num)draw v line

假象stdscr有个二维数组存储窗口中的内容,newwin是在这个二维数组中划分
在原有的stdscr窗口中创建新的窗口,

#include <unistd.h>
#include <stdio.h>
#include <ncurses.h>
#include <string.h>
#include <stdlib.h>

WINDOW* create_nwin(int h, int w, int y, int x)
{
    WINDOW* local_win;
    local_win = newwin(h, w, y, x);
    // box(local_win, 0, 0);
    wborder(local_win,'*','*','*','*','#','#','#','#');
    wrefresh(local_win);
    return local_win;
}

void del_win(WINDOW* local)
{
    wborder(local,' ',' ',' ',' ',' ',' ',' ',' ');
    wrefresh(local);
    delwin(local);
}

int main(int argc, char* argv[])
{
    initscr();
    curs_set(false);
    raw();
    keypad(stdscr, TRUE);
    noecho();
    
//
    
    WINDOW* myw;
    int w = 10, h = 7, x = (COLS-w)/2, y = (LINES-h)/2;
    int ch;
    printw("Press F1 to exit");
    refresh();
    myw = create_nwin(h, w, y, x);
    while ((ch = getch()) != KEY_F(1))
    {
        switch (ch)
        {
        case KEY_LEFT:
            del_win(myw);
            myw = create_nwin(h, w, y, --x);
            break;
        case KEY_RIGHT:
            del_win(myw);
            myw = create_nwin(h, w, y, ++x);
            break;
        case KEY_UP:
            del_win(myw);
            myw = create_nwin(h, w, --y, x);
            break;
        case KEY_DOWN:
            del_win(myw);
            myw = create_nwin(h, w, ++y, x);
            break;
        
        default:
            break;
        }
    }
    
///
    // getch();
    endwin();

}

九、颜色系统

声明说明
bool has_colors(void)检测当前终端是否支持颜色显示
int start_color()启动颜色机制,初始化相关内容
init_pair(颜色号,前景色,背景色)定义颜色对,定义好颜色对后就可以将号传给COLOR_PAIR(n)宏, attron(COLOR_PAIR(n))
init_color(COLOR_RED颜色名,R, G, B);改变某个颜色的RGB值, rgb的值从0到1000
color_content()
pair_content()
查看当前颜色设置
颜色
COLOR_BLACK0
COLOR_MAGENTA5洋红色
COLOR_CYAN6蓝绿,青色
COLOR_

easy menu

#include <stdio.h>
#include <ncurses.h>

#define WIDTH 30
#define HEIGHT 10

int startx = 0;
int starty = 0;
char* choices[] = {
    "File",
    "Edit",
    "Selection",
    "View"
};
int n_choices = sizeof(choices) / sizeof(char*);

void print_menu(WINDOW* menu_win, int highlight)
{
    int x = 2, y = 2;
    box(menu_win, 0, 0);
    for (int i = 0; i < n_choices; ++i)
    {
        if (highlight == i + 1)
        {
            wattron(menu_win, A_REVERSE);
            mvwprintw(menu_win, y, x, "%s", choices[i]);
            wattroff(menu_win, A_REVERSE);
        }
        else
        {
            mvwprintw(menu_win, y, x, "%s", choices[i]);
        }
        ++y;
    }
    wrefresh(menu_win);
}

void main()
{
    WINDOW* menu_win;
    int highlight = 1;
    int choice = 0;
    int c;
    initscr();
    curs_set(false);
    clear();
    noecho();
    raw();
    startx = (80 - WIDTH) / 2;
    starty = (24 - HEIGHT) / 2;
    menu_win = newwin(HEIGHT, WIDTH, starty, startx);
    keypad(menu_win, TRUE);
    mvprintw(0, 0, "Use");
    refresh();
    print_menu(menu_win, highlight);
    while (1)
    {
        c = wgetch(menu_win);
        switch (c)
        {
        case KEY_UP:
            if (highlight == 1)
            {
                highlight = n_choices;
            }
            else
            {
                --highlight;
            }
            break;
        case KEY_DOWN:
            if (highlight == n_choices)
            {
                highlight = 1;
            }
            else
            {
                ++highlight;
            }
            break;
        case 10:
            choice = highlight;
            break;
        default:
            mvprintw(24, 0, "press is %3d hopelly can be printed as %c", c, c);
            refresh();
            break;
        }
        print_menu(menu_win, highlight);
        if (choice != 0) break;
    }
    mvprintw(23, 0, "You cho %d with choice string %s\n", choice, choices[choice-1]);
    clrtoeol();
    refresh();
    endwin();
    
}

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在aarch64-none-linux-gnu架构上兼容ELF32,你需要进行一些额外的配置和操作。下面是一些步骤可以帮助你进行兼容性工作: 1. 安装32位兼容:首先,确保你的系统上已经安装了32位兼容。你可以使用以下命令安装: ``` sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 ``` 这将安装32位版本的Cncurses和标准C++。 2. 配置交叉编译环境:为了能够编译和链接32位的ELF,你需要设置正确的交叉编译环境。这可以通过设置环境变量来实现。例如,你可以设置以下变量: ``` export CC=aarch64-none-linux-gnu-gcc export CXX=aarch64-none-linux-gnu-g++ export LD=aarch64-none-linux-gnu-ld ``` 这将告诉编译器和链接器使用aarch64-none-linux-gnu工具链来进行编译和链接。 3. 更新编译选项:在构建你的应用程序时,确保使用正确的编译选项来生成32位的ELF文件。这可能涉及到设置 `-m32` 选项,如: ``` CFLAGS+=-m32 CXXFLAGS+=-m32 ``` 这将告诉编译器生成32位的目标文件。 4. 链接32位:当链接你的应用程序时,确保使用正确的链接选项来链接32位的ELF。这可能涉及到设置 `-m32` 选项和指定32位的路径,如: ``` LDFLAGS+=-m32 -L/path/to/32bit/libs LDLIBS+=-lmy32bitlib ``` 这将告诉链接器使用32位的进行链接。 通过执行上述步骤,你应该能够在aarch64-none-linux-gnu架构上兼容ELF32。请注意,具体的设置可能因你的系统和工具链而有所不同,所以请根据实际情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值