C指针原理教程之Ncurses介绍

1、安装Ncurses

Ncurses是一个能提供功能键定义(快捷键),屏幕绘制以及基于文本终端的图形互动功能的动态库。

Ncurses是一个能提供基于文本终端窗口功能的动态库. Ncurses可以:

· 只要您喜欢,您可以使用整个屏幕

· 创建和管理一个窗口

· 使用8种不同的彩色

· 为您的程序提供鼠标支持

· 使用键盘上的功能键

Ubuntu下

mysea@mysea-desktop:~$ sudo apt-get install libncurses5-dbg libncurses5-dev

mysea@mysea-desktop:~/test$ gcc -lncurses -o cursestest cursestest.c

Freebsd下

cd /usr/ports/devel/ncurses-devel

make install clean

2、hello,world

#include <curses.h>

int main(void){

  initscr();//初始化

  box(stdscr,ACS_VLINE,ACS_HLINE);//画边框

  mvaddstr(15,2,"hello,world");//在15,2显示字符串

  refresh();//刷新屏幕

  getch();//等待按键

  endwin();//结束

  return 0;  

}

编译及运行

dp@dp:~/cursestest % gcc -lncurses 1.c -o mytest

dp@dp:~/cursestest % ./mytest

3、色彩

然后编写下面代码:

#include <ncurses.h>

#include <locale.h>

#include <stdio.h>

int main(void){

//init_pair(short index,short foreground,short background)初始化颜色索引

//attron(COLOR_PAIR(索引号)|属性)

  setlocale(LC_ALL,"");

  initscr();//初始化

  box(stdscr,ACS_VLINE,ACS_HLINE);//画边框

  if (!has_colors()||start_color()==ERR){

    endwin();

    printf("终端不支持颜色\n");

    return 0;

  }

  init_pair(1,COLOR_GREEN,COLOR_BLACK);

  init_pair(2,COLOR_RED,COLOR_BLACK);

  init_pair(3,COLOR_WHITE,COLOR_BLUE);

  int i=0;

  for (i=1;i<=3;i++){

     attron(COLOR_PAIR(i));

     move(i,10);

     printw("hello,world:%d",i);

  }

  for (i=1;i<=3;i++){

     attron(COLOR_PAIR(i)|A_UNDERLINE);

     move(i+5,10);

     printw("hello,world:%d",i);

  }

  refresh();//刷新屏幕

  getch();//等待按键

  endwin();//结束

执行

4、对中文的支持

dp@dp:~/cursestest % cat 1.c

#include <ncurses.h>

#include <locale.h>

#include <stdio.h>

int main(void){

//init_pair(short index,short foreground,short background)初始化颜色索引

//attron(COLOR_PAIR(索引号)|属性)

  setlocale(LC_ALL,"");

  initscr();//初始化

  box(stdscr,ACS_VLINE,ACS_HLINE);//画边框

  if (!has_colors()||start_color()==ERR){

    endwin();

    printf("终端不支持颜色\n");

    return 0;

  }

  init_pair(1,COLOR_GREEN,COLOR_BLACK);

  init_pair(2,COLOR_RED,COLOR_BLACK);

  init_pair(3,COLOR_WHITE,COLOR_BLUE);

  int i=0;

  for (i=1;i<=3;i++){

     attron(COLOR_PAIR(i));

     move(i,10);

     printw("hello,世界%d",i);

  }

  for (i=1;i<=3;i++){

     attron(COLOR_PAIR(i)|A_UNDERLINE);

     move(i+5,10);

     printw("hello,世界:%d",i);

  }

  refresh();//刷新屏幕

  getch();//等待按键

  endwin();//结束

  return 0;  

}

编译时注意要使用ncursesw库,不使用ncurses库

dp@dp:~/cursestest % gcc -lncursesw 1.c -o mytest

dp@dp:~/cursestest % ./mytest

5、窗口与子窗口

dp@dp:~/cursestest % cat 1.c

#include <ncurses.h>
#include <locale.h>
int main(){
//init_pair(short index,short foreground,short background)初始化颜色索引
//attron(COLOR_PAIR(索引号)|属性)
//newwin建立窗口,derwin建立窗口的子窗口(相对于父窗口相对位置),subwin建立窗口的子窗口(相对于根窗口绝对位置)
  setlocale(LC_ALL,"");
  WINDOW *win1,*win2,*subwin;
  initscr();//初始化
  win1=newwin(15,50,1,1);//新窗口(行,列,begin_y,begin_x)
  box(win1,ACS_VLINE,ACS_HLINE);
  mvwprintw(win1,1,1,"WIN1");
  mvwprintw(win1,2,1,"您好,很高兴认识您");
  win2=newwin(10,40,10,30);//新窗口(行,列,begin_y,begin_x)
  box(win2,ACS_VLINE,ACS_HLINE);
  mvwprintw(win2,1,1,"WIN2");
  mvwprintw(win2,2,1,"您好,很高兴认识您");
  subwin=derwin(win2,3,20,3,5); //子窗口
  box(subwin,ACS_VLINE,ACS_HLINE);
  mvwprintw(subwin,1,5,"按任意键退出");//(窗口,y,x,字符串)
  refresh();//刷新整个大窗口stdscr
  wrefresh(win1);
  wrefresh(win2);
  touchwin(win1);//转换当前窗口为win1
  wrefresh(win1);
  getch();//win1显示完,等待按键显示win2
  touchwin(win2);//转换当前窗口为win2
  //使用doupdate,可以事先定义要刷新的部分,然后刷新
  wnoutrefresh(win2);
  wnoutrefresh(subwin);
  doupdate();
  getch();//等待按键
  delwin(win1);
  delwin(subwin);
  delwin(win2);
  endwin();//结束
  return 0;
}

dp@dp:~/cursestest % gcc -lncursesw 1.c -o mytest
dp@dp:~/cursestest % ./mytest

6、自动滚屏

dp@dp:~/cursestest % cat 2.c

#include <ncurses.h> 

#include <locale.h> 

int main(void){ 

  int y,x,i,j,h,w;

  setlocale(LC_ALL,""); 

  WINDOW *pad; 

  initscr();//初始化 

  getmaxyx(stdscr,h,w);//获得屏幕尺寸 

  //画背景

  for(i=0;i<h;i++){

     for(j=0;j<w;j++){

       mvaddch(i,j,ACS_CKBOARD);

     }

  }

  refresh();

  //建立窗口

  pad=newpad(80,90);
  for (i=0;i<80;i++){

    char line[90];

    sprintf(line,"line %d\n",i);

    mvwprintw(pad,i,1,line);

  }

  refresh();

  prefresh(pad,0,1,5,10,20,25);//刷新pad。0,1 为基垫需要显示区域的左上角置(行列对,以下同此)。5,10,20,45为屏幕显示区域的左上角和右下角位置

  for(i=0;i<65;i++){

    prefresh(pad,i+1,1,5,10,20,25);//刷新pad,实现流屏;

    usleep(30000); 

  }

  getch();//等待按键

  delwin(pad); 

  endwin();//结束 

  return 0;  

}

dp@dp:~/cursestest % gcc -lncursesw 2.c -o mytest

dp@dp:~/cursestest % ./mytest

7、在窗口中移动光标

dp@dp:~/cursestest % cat 2.c

#include <ncurses.h> 

#include <locale.h> 

int main(void){ 

//init_pair(short index,short foreground,short background)初始化颜色索引 

//attron(COLOR_PAIR(索引号)|属性) 

//newwin建立窗口,derwin建立窗口的子窗口(相对于父窗口相对位置),subwin建立窗的子窗口(相对于根窗口绝对位置) 

  int x,y;

  setlocale(LC_ALL,""); 

  WINDOW *win1,*win2,*subwin; 

  initscr();//初始化 

  win1=newwin(15,50,1,1);//新窗口(行,列,begin_y,begin_x) 

  box(win1,ACS_VLINE,ACS_HLINE); 

  mvwprintw(win1,1,1,"WIN1"); 

  mvwprintw(win1,2,1,"myhaspl@myhaspl.com"); 

  win2=newwin(10,40,10,30);//新窗口(行,列,begin_y,begin_x) 

  box(win2,ACS_VLINE,ACS_HLINE); 

  wmove(win2,1,1);//移动某窗口的光标

  printw("WIN2");

  wmove(win2,2,1);//移动某窗口的光标。(窗口,y,x)

  printw("myhaspl@myhaspl.com"); 

  subwin=derwin(win2,3,20,4,5); //子窗口 

  box(subwin,ACS_VLINE,ACS_HLINE); 

  mvwprintw(subwin,1,5,"按任意键退出");//(窗口,y,x,字符串) 

  refresh();//刷新整个大窗口stdscr 

  wrefresh(win1); 

  wrefresh(win2); 

  move(5,60);//在stdscr移动光标

  printw("hello.........");

  touchwin(win1);//转换当前窗口为win1 

  wrefresh(win1); 

  getch();//win1显示完,等待按键显示win2 

  touchwin(win2);//转换当前窗口为win2 

  //使用doupdate,可以事先定义要刷新的部分,然后刷新 

  wnoutrefresh(win2);  

  wnoutrefresh(subwin); 

  doupdate(); 

  getyx(subwin,y,x);//获得当前逻辑光标位置

  mvwprintw(subwin,y+1,x,"................");//在“按任意键退出"下一行输出"..............."

  getch();//等待按键 

  delwin(win1); 

  delwin(subwin); 

  delwin(win2); 

  endwin();//结束 

  return 0;  

}

编译后运行

dp@dp:~/cursestest % gcc -lncursesw 2.c -o mytest

dp@dp:~/cursestest % ./mytest

8、菜单

dp@dp:~/cursestest % cat 2.c

#include <locale.h>

#include <menu.h> 

#include <stdio.h>

#include <ctype.h>

//定义菜单项

static const char *menus[]={

  "1-1","1-2","1-3","2-1","2-2","2-3"

};

#define CITEM sizeof(menus)/sizeof(menus[0])//菜单项数

ITEM *items[CITEM];

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

  int i;

  int ch;

  int mrows,mcols;

  WINDOW *win,*subwin;

  MENU *mymenu;

  //初始化屏幕

  initscr();

  //不用等待回车键

  cbreak();

  //不回显

  noecho();

  //可以处理功能键 

  keypad(stdscr,TRUE); 

  //建立菜单项

  for(i=0;i<CITEM;i++){

    items[i]=new_item(menus[i],menus[i]);//第二个参数为菜单项的描述

  } 

  //建立菜单

  mymenu=new_menu(items);

  set_menu_format(mymenu,CITEM,1);  //设置CITEM行1列的菜单

  set_menu_mark(mymenu,">");//菜单选中的MARK

  //获得菜单的行列数

  scale_menu(mymenu,&mrows,&mcols);

  //建立窗口和子窗口

  win=newwin(mrows+2,mcols+2,3,30);

  keypad(win,TRUE);

  box(win,0,0);

  subwin=derwin(win,0,0,1,1);

  //设置菜单的窗口

  set_menu_sub(mymenu,subwin);  

  //在子窗口上放置菜单

  post_menu(mymenu);

  refresh();

  wrefresh(win);

  //获得输入,并移动选择到相应的菜单项 

  while(toupper(ch=wgetch(win))!='\n'){

     if(ch==KEY_DOWN)

       menu_driver(mymenu,REQ_DOWN_ITEM);//移动菜单选择

     else if(ch==KEY_RIGHT)

       menu_driver(mymenu,REQ_RIGHT_ITEM);

     else if (ch==KEY_UP)

       menu_driver(mymenu,REQ_UP_ITEM); 

     else if (ch==KEY_LEFT)

       menu_driver(mymenu,REQ_LEFT_ITEM);

  }

  //输出当前项

  mvprintw(LINES-2,0,"you select the item :%s\n",item_name(current_item(mymenu)));

  refresh();

  unpost_menu(mymenu);

  getch();

  //释放内存

  free_menu(mymenu);

  for(i=0;i<CITEM;i++) free_item(items[i]);

  endwin();

  return 1;

}

编译并运行

dp@dp:~/cursestest % gcc -lncursesw -lmenu 2.c -o mytest

dp@dp:~/cursestest % ./mytest

(0)

相关推荐

  • C指针原理教程之C内嵌汇编

    内联汇编的重要性体现在它能够灵活操作,而且可以使其输出通过 C 变量显示出来.因为它具有这种能力,所以 "asm" 可以用作汇编指令和包含它的 C 程序之间的接口.简单得说,内联汇编,就是可以让程序员在C语言中直接嵌入汇编代码,并与汇编代码交互C程序中的C表达式,享受汇编的高运行效率. 内联汇编的格式是直接在C代码中插入以下格式: asm( .... .... ) 其中的"..."为汇编代码,比如下面例子中,在 result=a*b和printf("%d\

  • C指针原理教程之C快速入门

    一.C简介 1.C语言简介 C语言是一门语法 精简的语言,它的关键字仅有32个,C语言以main函数为主函数,程序编译运行后后,执行的就是main函数的内容,因此,纵观很多C语言程序,形成了一道有趣的风景线:头文件和许多c代码文件以main函数为中心和起始点构造,在main函数中调用了这些文件中编写的代码,引用头文件.C语言程序实质就是在程序中调用 C标准库提供的函数.其它C库提供的函数.操作系统提供的API接口.自己定义的函数,同时应用适当的数据结构和算法来完成工作. C语言虽然精简,但却很强

  • C指针原理教程之语法树及其实现

    下面完成一个简单的计算器通过语法树进行计算,首先定义一个语法树的结构,然后编写flex文件,解析数字或符号,对于 符号返回本身,对于数字,返回NUMBER,并对yylval的d进行赋值,yylval指向一个联合类型,接着,在语法分析器中完成语法树的节点的增加,分别对应数字和符号有不同的增加方式,最后有一个单独的C代码处理计算,以及语法树相关计算的函数.对结果的计算的方式是对语法树进行递归. 词法分析器为: dp@dp:~/flexbison % cat myast.l %option noyyw

  • C指针原理教程之编译原理-小型计算器实现

    1.打开cygwin,进入home目录,home目录在WINDOWS系统的cygwin安装目录映射为home目录. 2.首先,在home目录中新建文件夹,在文件夹中放置如下内容的test1.l /*统计字数*/ %{ int chars=0; int words=0; int lines=0; %} %% [a-zA-Z]+ {words++;chars+=strlen(yytext);} \n {chars++;lines++;} . {chars++;} %% main(int argc,c

  • C指针原理教程之AT&T汇编

    汇编在LINUX系统下的意义远远大于WINDOWS系统,LINUX内核部分代码就是汇编编写的.然后,绝大多数 Linux 程序员以前只接触过DOS/Windows 下的汇编语言,这些汇编代码都是 Intel 风格的.但在 Unix 和 Linux 系统中,更多采用的还是 AT&T 格式,两者在语法格式上有着很大的不同,因此应对AT&T汇编应有一个基本的了解和熟悉. 我们在LINUX下用C编写一段最简单的helloworld程序,命令为hello.c #include <stdio.h

  • C指针原理教程之垃圾回收-内存泄露

    一.内存泄露 1.正常的链表操作 下面程序建立一个10元素的链表,输出它们的节点,每个节点是一个员工的工号和年龄.最后删除每个节点,释放列表. dp@dp:~/memorytest % cat 1.c #include <stdlib.h> #include <stdio.h> //code:myhaspl@myhaspl.com //author:myhaspl //date:2014-01-10 typedef struct listnode mynode; struct li

  • C指针原理教程之C指针基础

    tcctok.h定义了C语言的词法分析的基本元素,主要定义了关键字. / keywords /      DEF(TOK_INT, "int")      DEF(TOK_VOID, "void")      DEF(TOK_CHAR, "char")      DEF(TOK_IF, "if")      DEF(TOK_ELSE, "else")      DEF(TOK_WHILE, "wh

  • C指针原理教程之Ncurses介绍

    1.安装Ncurses Ncurses是一个能提供功能键定义(快捷键),屏幕绘制以及基于文本终端的图形互动功能的动态库. Ncurses是一个能提供基于文本终端窗口功能的动态库. Ncurses可以: · 只要您喜欢,您可以使用整个屏幕 · 创建和管理一个窗口 · 使用8种不同的彩色 · 为您的程序提供鼠标支持 · 使用键盘上的功能键 Ubuntu下 mysea@mysea-desktop:~$ sudo apt-get install libncurses5-dbg libncurses5-d

  • java编程之xpath介绍

    一.使用dom4j支持XPATH的操作 -可以直接获取到某个元素,而不用一层一层的解析获取 XPATH如何使用: 第一种形式:/AAA/BBB/CCC,一个/代表一层,表示获取到AAA下面的BBB下面的CCC 第二种形式://BBB,表示和这个名称相同的都可以得到,只要名称是BBB都可以得到.//DDD/BBB:得到所有DDD下面的所有的BBB 第三种形式:/AAA/BBB/CCC/*,得到所有AAA下面BBB下面CCC下面的所有的元素./*/*/*/BBB,表示限制前三层,前三层无论是什么名称

  • Swift中的指针操作和使用详细介绍

    Apple期望在Swift中指针能够尽量减少登场几率,因此在Swift中指针被映射为了一个泛型类型,并且还比较抽象.这在一定程度上造成了在Swift中指针使用的困难,特别是对那些并不熟悉指针,也没有多少指针操作经验的开发者(包括我自己也是)来说,在Swift中使用指针确实是一个挑战.在这篇文章里,我希望能从最基本的使用开始,总结一下在Swift中使用指针的一些常见方式和场景.这篇文章假定你至少知道指针是什么,如果对指针本身的概念不太清楚的话,可以先看看这篇五分钟C指针教程(或者它的中文版本),应

  • c++ 指针与引用的区别介绍及使用说明

    指针与引用看上去完全不同(指针用操作符"*"和"->",引用使用操作符"."),但是它们似乎有相同的功能.指针与引用都是让你间接引用其他对象.你如何决定在什么时候使用指针,在什么时候使用引用呢? 首先,要认识到在任何情况下都不能使用指向空值的引用.一个引用必须总是指向某些对象.因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时你应该把变量声明为指针,因为这样你可以赋空值给该变量.相反,如果变量肯定指向一

  • Go语言中结构体方法副本传参与指针传参的区别介绍

    GO语言结构体方法跟结构体指针方法的区别 首先,我定了三个接口.一个结构和三个方法: type DeptModeA interface { Name() string SetName(name string) } type DeptModeB interface { Relocate(building string, floor uint8) } type Dept struct { name string building string floor uint8 Key string } fun

  • Node.js 异步编程之 Callback介绍(一)

    Node.js 基于 JavaScript 引擎 v8,是单线程的.Node.js 采用了与通常 Web 上的 JavaScript 异步编程的方式来处理会造成阻塞的I/O操作.在 Node.js 中读取文件.访问数据库.网络请求等等都有可能是异步的.对于 Node.js 新人或者从其他语言背景迁移到 Node.js 上的开发者来说,异步编程是比较痛苦的一部分.本章将由浅入深为大家讲解 Node.js 异步编程的方方面面.从最基础的 callback 到 thunk.Promise.co 直到

随机推荐