关于Unix上读取键盘输入的问题(curses)

zhongxh 2002-11-01 09:54:29
大家用过curses编程,对于PageUp和ESC的读取,我似乎无法解决,如果确实想按ESC,
似乎 if ( in_char == -1 ) 不能立刻得到, 而在按了下一个键后,就返回了ESC.

请有过这方面经验的帮忙。

in_char = getch();

if ( in_char == CTL_V ) return KEY_PGDN;
else
if ( in_char != ESC ) return in_char;

in_char = getch();

if ( in_char == -1 ) return ESC;
else
if ( in_char == 'v' ) return KEY_PGUP;
else
if ( in_char == '[' )
{
in_char = getch();
switch ( in_char )
{
case 'A': return KEY_UP;
case 'B': return KEY_DOWN;
case 'C': return KEY_RIGHT;
case 'D': return KEY_LEFT;
case 'H': return KEY_A1;
case 'J': return KEY_A3;
case 'K': return KEY_C3;
...全文
562 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhongxh 2002-11-01
  • 打赏
  • 举报
回复
magma,多谢, 不过这个方法不对。
magma 2002-11-01
  • 打赏
  • 举报
回复
这个问题估计是你参数设置的不对,试一试
在你的getch调用前使用这两个函数
nonl();
raw();
应该就可以解决你那个问题
zhongxh 2002-11-01
  • 打赏
  • 举报
回复
非常感谢,不过,由于目前大部分功能都使用了curses,很多窗口, 读键盘这部分改为ioctl不太方便, 麻烦大家帮我想想。

感谢jennyvenus。
用户 昵称 2002-11-01
  • 打赏
  • 举报
回复
tty.c_cc[VMIN] = 0 ; // MIN
tty.c_cc{VTIME] = 2 ; // TIME
用户 昵称 2002-11-01
  • 打赏
  • 举报
回复
我没用用过curses,我用的是ioctl,设置终端类型为0个缓冲,每次读键盘0.2秒没有东西返回一个特定值,代码和你的差不多
#include <stdio.h>
#include <termio.h>
static struct termio ttysave ;
void restore() ;
char getch() ;

main()
{
puts( "---------------------------" ) ;
puts( "enter a key : " );
getch() ;
puts( "\n--------------" );
exit( 0 );
}

char getch()
{
static char ch ;
static int total, flag = 1 ;
struct termio tty ;

if( flag )
{
flag = 0 ;
if( ioctl( 0, TCGETA, &tty ) == -1 )
{
perror( "ioctl" );
exit( -1 );
}
ttysave = tty ;
tty.c_lflag &= ~( ICANON | ECHO | ISIG ) ;
tty.c_cc[VMIN] = 1 ; // MIN
tty.c_cc{VTIME] = 0 ; // TIME
if( ioctl( 0, TCSETAF, &tty ) == -1 )
{
restore();
perror( "ioctl" );
exit( -2 );
}
}

switch( total = read( 0, &ch, 1 ))
{

case -1 :
restore() ;
perror( "read" );
exit( 3 );
case 0:
restore():
fputs( "EOF error!", stderr );
exit( 4 ) ;
default:
.....
}

restore();
return( ch );
}


void restore()
{
if( ioctl( 0, TCSETAF, &ttysave ) == -1 )
{
perror( "ioctl" );
exit( 5 );
}
return ;
}
这是初始化部分
用户 昵称 2002-11-01
  • 打赏
  • 举报
回复
我见过linux下的turbo vision,不知道从那里有没有帮助。
用户 昵称 2002-11-01
  • 打赏
  • 举报
回复

表 D-1. 终端仿真类型

选择
选项

Console Redirection
(控制台重定向)
具有一个串行端口的系统:
On(开)
Off(关)

Remote Terminal Type
(远程终端类型)
VT100/220
ANSI

Redirection after boot
(引导后重定向)
Enabled(已启用)
Disabled(已禁用)




表 D-2. VT100/220 支持的转义序列

按键
支持的序列
终端仿真

上箭头键
<Esc> [ <Shift>a
VT100/220

下箭头键
<Esc> [ <Shift>b
VT100/220

右箭头键
<Esc> [ <Shift>c
VT100/220

左箭头键
<Esc> [ <Shift>d
VT100/220

F1 键
<Esc> <Shift>op
VT100/220

F2 键
<Esc> <Shift>oq
VT100/220

F3 键
<Esc> <Shift>or
VT100/220

F4 键
<Esc> <Shift>os
VT100/220

F5 键
<Esc> <Shift>ot
VT100

F6 键
<Esc> <Shift>ou
<Esc> [ 1 7 ~
VT100
VT100/220

F7 键
<Esc> <Shift>ov
<Esc> [ 1 8 ~
VT100
VT100/220

F8 键
<Esc> <Shift>ow
<Esc> [ 1 9 ~
VT100
VT100/220

F9 键
<Esc> <Shift>ox
<Esc> [ 2 0 ~
VT100
VT100/220

F10 键
<Esc> <Shift>oy
<Esc> [ 2 1 ~
VT100
VT100/220

F11 键
<Esc> <Shift>oz
<Esc> [ 2 3 ~
VT100
VT100/220

F12 键
<Esc> <Shift>oa
<Esc> [ 2 4 ~
VT100
VT100/220

Home 键
<Esc> [ 1 ~
VT220

End 键
<Esc> [ 4 ~
VT220

Insert 键
<Esc> [ 2 ~
VT220

Delete 键
<Esc> [ 3 ~
VT220

Page Up 键
<Esc> [ 5 ~
VT220

Page Down 键
<Esc> [ 6 ~
VT220

Shift-Tab 键
<Esc> [ <Shift>z
<Esc> [ 0 <Shift>z
VT100
VT220






表 D-3. ANSI 支持的转义序列

按键
支持的序列

上箭头键
<Esc> [ <Shift>a

下箭头键
<Esc> [ <Shift>b

右箭头键
<Esc> [ <Shift>c

左箭头键
<Esc> [ <Shift>d

F1 键
<Esc> <Shift>op

F2 键
<Esc> <Shift>oq

F3 键
<Esc> <Shift>or

F4 键
<Esc> <Shift>os

F5 键
<Esc> <Shift>ot

F6 键
<Esc> <Shift>ou

F7 键
<Esc> <Shift>ov

F8 键
<Esc> <Shift>ow

F9 键
<Esc> <Shift>ox

F10 键
<Esc> <Shift>oy

F11 键
<Esc> <Shift>oz

F12 键
<Esc> <Shift>oa




表 D-4. 其它转义序列

组合键
支持的序列

<Alt><x>
<Alt><x> 被映射至终端上的 <Esc> <Shift> x <Shift> x 按键序列,其中 x 表示小写字母,X 表示大写字母。

<Ctrl><Alt><Del>

(该组合键用于重新引导
系统。)
<Esc> <Shift>r <Esc> r <Esc> <Shift>r


<Ctrl><Shift>i
<Esc> <Ctrl><Shift>i

<Ctrl><Shift>j
<Esc> <Ctrl><Shift>j

<Ctrl><Shift>h
<Esc> <Ctrl><Shift>h

<Ctrl><Shift>m
<Esc> <Ctrl><Shift>m

<Ctrl>2
<Esc> <Ctrl>2
如果要有程序中使用功能键,需要在新建屏幕后设置屏幕的属性,具体的方法就是调用 keypad(win, TRUE);这个函数。
这样,就可以用系统定义的宏来检查输入的键值了,比如F1对应的键是 KEY_F(1)等等。
如果不调用keypad(win, TRUE)的话,那么在使用功能键的时候就会出现楼上所说的情况了。
其实功能键不是单独的一个键值,而是以27开头的一串键值,所以你的测试程序才会觉得很多键都返回27.如果你用一个循环来读键的话,你就可以看到一般的功能键会返回两个甚至四个键值了。

page不好办,我没找到相应的东西,继续灌水
zhongxh 2002-11-01
  • 打赏
  • 举报
回复
jennyvenus: 感动, 这篇文章是很经典的,你也许注意到了,其例子中没有NPAGE和PPAGE,呵呵。
magma(澎湃) :您的这个程序,如果按ESC或PgUp都是返回0x1b,就是27。

再想办法。多谢了。
用户 昵称 2002-11-01
  • 打赏
  • 举报
回复
KEY_UP 0403 ↑
KEY_DOWN 0402 ↓
KEY_LEFT 0404 ←
KEY_RIGHT 0405 →
KEY_HOME 0406 Home key (upward+left arrow)
KEY_BACKSPACE 0407 backspace (unreliable)
KEY_F0 0410 Function keys.
KEY_F(n) (KEY_F0+(n)) formula for f .
KEY_NPAGE 0522 Next page
KEY_PPAGE 0523 Previous page

以上仅列出笔者较常使用的一些控制键, 至於其他控制键的定义, 请自行参

阅 man curses (* 注三)

一并为您列出其他常用的一些特殊字元

[TAB] /t
[ENTER] /r
[ESC] 27
[BACKSPACE] 127


■ 如何改变萤幕显示字元的属性

为了使输出的萤幕画面更为生动美丽, 我们常须要在萤幕上做一些如反白,

闪烁等变化. curses 定义了一些特殊的属性, 透过这些定义, 我们也可以

在 curses 程式□控制萤幕的输出变化.

attron(mod) 开启属性
attroff(mod) 关闭属性

curses.h 里头定义了一些属性, 如:

A_UNDERLINE 加底线
A_REVERSE 反白
A_BLINK 闪烁
A_BOLD 高亮度
A_NORMAL 标准模式 (只能配合 attrset() 使用)


当使用 attron() 开启某一种特殊属性模式後, 接下来在萤幕的输出都会以

该种属性出现. 直到您呼叫 attroff() 将此模式关闭.

请注意, 当您欲 attron() 开启另一种属性时, 请记得利用 attroff()先关

闭原来的属性, 或直接以 attrset(A_NORMAL) 将所有特殊属性关闭.否则,

curses 会将两种属性做重叠处理.

□例:

attrset(A_NORMAL); /* 先将属性设定为正常模式 */

attron(A_UNDERLINE); /* 加底线 */

mvaddstr(9,10,"加底线"); /* 加底线输出一串字元 */

attroff(A_UNDERLINE); /* 关闭加底线模式, 恢复正常模式 */

attron(A_REVERSE); /* 开启反白模式 */

mvaddstr(10,10,"反白"); /* 输出一串反白字元 */

attroff(A_REVERSE); /* 关闭反白模式, 恢复正常模式 */

attron(A_BLINK); /* 开启闪烁模式 */

mvaddstr(11,10,"闪烁"); /* 输出一串闪烁字元 */

attroff(A_BLINK); /* 关闭闪烁模式, 恢复正常模式 */

attron(A_BOLD); /* 开启高亮度模式 */

mvaddstr(12,10,"高亮度"); /* 输出一串高亮度字元 */

attroff(A_BOLD); /* 关闭高亮度模式, 恢复正常模式 */



■ 其他常用的一些函式

beep() 发出一声哔声
box(win,ch1,ch2) 自动画方框 ch1: 画方框时垂直方向所用字元
ch2: 画方框时水平方向所用字元

example: box(stdscr,'|','-');
将以 | 及 - 围成一个方框

■ 应用完整□例

下面所举的例子, 即完全利用刚刚所介绍的含式来完成.这个程式可将从键

盘上读取的字元显示在萤幕上, 并且可以上下左右方向键来控制游标的位置

, 当按下 [ESC] 後, 程式即结束.

您有没有发现, 这不就是一个简单全萤幕编辑器的雏形吗?


#include <curses.h> /* 引进 curses.h , 并自动引进
stdio.h */


#define StartX 1 /* 决定游标初始位置 */
#define StartY 1

void initial();

main()
{
int x=StartX; /* 宣告 x,y 并设定其初值
*/

int y=StartY;
int ch; /* 宣告 ch 为整数,配合 getch()
使用 */


initial(); /* 呼叫 initial(), 启动 curses
模式, */

/* 并完成其它设定
*/


box(stdscr,'|','-'); /* 画方框
*/


attron(A_REVERSE); /* 开启反白模式
*/

mvaddstr(0,20,"Curses Program"); /* 在 (20,0) 处输出反白字元
*/

attroff(A_REVERSE); /* 关闭反白模式
*/


move(x,y); /* 将游标移至初始位置
*/


do { /* 以无限回圈不断等待输入
*/

ch=getch(); /* 等待自键盘输入字元
switch(ch) { /* 判断输入字元为何
*/


case KEY_UP: --y; /* 判断是否"↑"键被按下
*/

break;
case KEY_DOWN: ++y; /* 判断是否"↓"键被按下
*/

break;
case KEY_RIGHT: ++x; /* 判断是否"→"键被按下
*/

break;
case KEY_LEFT: --x; /* 判断是否"←"键被按下
*/

break;
case '\r': /* 判断是否 ENTER 键被按下
*/

++y;
x=0;
break;
case '\t': /* 判断是否 TAB 键被按下
*/

x+=7;
break;
case 127: /* 判断是否 BACKSPACE 键被按下
*/

mvaddch(y,--x,' ');/* delete 一个字元
*/

break;

case 27: endwin(); /* 判断是否[ESC]键被按下
*/

exit(1); /* 结束 curses 模式
*/

/* 结束此程式
*/


default:
addch(ch); /* 如果不是特殊字元, 将此字元印
出 */

x++;
break;
}
move(y,x); /* 移动游标至现在位置
*/

} while (1);
}

void initial() /* 自定开启 curses 函式
*/

{
initscr();
cbreak();
nonl();
noecho();
intrflush(stdscr,FALSE);
keypad(stdscr,TRUE);
refresh();
}



■ 後记

学完了上述的一些命令, 相不相信您已经可以写出一个漂亮的全萤幕编辑
器了? 事实上, curses 提供的函式不下 200 个, 可是笔者认为, 一切再
复杂的函式都可以用本文提到的一些组合变化而成, 学了太多的函式, 只
是徒增自己困扰罢了. 当然, 如果您对其它函式有兴趣, 可以自行参阅
curses 说明档. ( 方法: % man curses ) 本文不过行抛砖引玉之效, 也
希望未来能陆续出现更多同学自行创作的程式.

* 任何疑问及建议, 欢迎 e-mail 至 ljh@CCCA.NCTU.edu.tw. 谢谢 ! *



注一:
请参考 /usr/share/lib/termcup
/usr/share/lib/terminfo/s/sun

注二:
1.如果是 BSD 的版本, 需使用
cc [file.c] -lcurses -ltermcap 来完成 compile.
2.计中工作站不知何故将原来的 /usr/5bin/cc 更改为 /usr/5bin/cc.org

因此, 您若想在计中工作站 compile curses 程式.需以 /usr/5bin/cc.
org
取代 /usr/5bin/cc , 否则 compile 可能发生错误.
3.较旧版的 curses 需同时引进 curses 和 termlib 这两个 library,
因此, 您必须使用 /usr/5bin/cc [file.c] -lcurses -ltermlib 来
compile.

注三:
根据笔者的经验, 上下左右方向键应可正常使用而不会发生问题, 但其它

如 PgUp,PgDn,功能键,Home,End 等特殊键, 很容易因机器, 键盘不同而无

法使用, 因此, 若您的程式须要在不同的机器上使用, 建议您只用方向键来

控制, 其它的特殊键少用为妙.
至於 PgUp,PgDn 一些特殊键的控制方法, 由於较为复杂, 有兴趣的同学可

考 tin 原始程式 curses.c 内所使用的一些方法.
magma 2002-11-01
  • 打赏
  • 举报
回复

#include <stdio.h>
#include <curses.h>

main()
{
int c;

initscr();
nonl();
raw();
noecho();

keypad(stdscr, 1);
mvwprintw(stdscr, 0, 1, "Please Input Key:");
refresh();
c = getch();
mvwprintw(stdscr, 20, 1, "input key:0x%x", c);
refresh();

endwin();

return 0;
}

不应该吧,给你一段我测试的代码,你参考一下好了
用户 昵称 2002-11-01
  • 打赏
  • 举报
回复
KEY_UP 0403 ↑
KEY_DOWN 0402 ↓
KEY_LEFT 0404 ←
KEY_RIGHT 0405 →
KEY_HOME 0406 Home key (upward+left arrow)
KEY_BACKSPACE 0407 backspace (unreliable)
KEY_F0 0410 Function keys.
KEY_F(n) (KEY_F0+(n)) formula for f .
KEY_NPAGE 0522 Next page
KEY_PPAGE 0523 Previous page

以上仅列出笔者较常使用的一些控制键, 至於其他控制键的定义, 请自行参

阅 man curses (* 注三)

一并为您列出其他常用的一些特殊字元

[TAB] /t
[ENTER] /r
[ESC] 27
[BACKSPACE] 127


■ 如何改变萤幕显示字元的属性

为了使输出的萤幕画面更为生动美丽, 我们常须要在萤幕上做一些如反白,

闪烁等变化. curses 定义了一些特殊的属性, 透过这些定义, 我们也可以

在 curses 程式□控制萤幕的输出变化.

attron(mod) 开启属性
attroff(mod) 关闭属性

curses.h 里头定义了一些属性, 如:

A_UNDERLINE 加底线
A_REVERSE 反白
A_BLINK 闪烁
A_BOLD 高亮度
A_NORMAL 标准模式 (只能配合 attrset() 使用)


当使用 attron() 开启某一种特殊属性模式後, 接下来在萤幕的输出都会以

该种属性出现. 直到您呼叫 attroff() 将此模式关闭.

请注意, 当您欲 attron() 开启另一种属性时, 请记得利用 attroff()先关

闭原来的属性, 或直接以 attrset(A_NORMAL) 将所有特殊属性关闭.否则,

curses 会将两种属性做重叠处理.

□例:

attrset(A_NORMAL); /* 先将属性设定为正常模式 */

attron(A_UNDERLINE); /* 加底线 */

mvaddstr(9,10,"加底线"); /* 加底线输出一串字元 */

attroff(A_UNDERLINE); /* 关闭加底线模式, 恢复正常模式 */

attron(A_REVERSE); /* 开启反白模式 */

mvaddstr(10,10,"反白"); /* 输出一串反白字元 */

attroff(A_REVERSE); /* 关闭反白模式, 恢复正常模式 */

attron(A_BLINK); /* 开启闪烁模式 */

mvaddstr(11,10,"闪烁"); /* 输出一串闪烁字元 */

attroff(A_BLINK); /* 关闭闪烁模式, 恢复正常模式 */

attron(A_BOLD); /* 开启高亮度模式 */

mvaddstr(12,10,"高亮度"); /* 输出一串高亮度字元 */

attroff(A_BOLD); /* 关闭高亮度模式, 恢复正常模式 */



■ 其他常用的一些函式

beep() 发出一声哔声
box(win,ch1,ch2) 自动画方框 ch1: 画方框时垂直方向所用字元
ch2: 画方框时水平方向所用字元

example: box(stdscr,'|','-');
将以 | 及 - 围成一个方框

■ 应用完整□例

下面所举的例子, 即完全利用刚刚所介绍的含式来完成.这个程式可将从键

盘上读取的字元显示在萤幕上, 并且可以上下左右方向键来控制游标的位置

, 当按下 [ESC] 後, 程式即结束.

您有没有发现, 这不就是一个简单全萤幕编辑器的雏形吗?


#include <curses.h> /* 引进 curses.h , 并自动引进
stdio.h */


#define StartX 1 /* 决定游标初始位置 */
#define StartY 1

void initial();

main()
{
int x=StartX; /* 宣告 x,y 并设定其初值
*/

int y=StartY;
int ch; /* 宣告 ch 为整数,配合 getch()
使用 */


initial(); /* 呼叫 initial(), 启动 curses
模式, */

/* 并完成其它设定
*/


box(stdscr,'|','-'); /* 画方框
*/


attron(A_REVERSE); /* 开启反白模式
*/

mvaddstr(0,20,"Curses Program"); /* 在 (20,0) 处输出反白字元
*/

attroff(A_REVERSE); /* 关闭反白模式
*/


move(x,y); /* 将游标移至初始位置
*/


do { /* 以无限回圈不断等待输入
*/

ch=getch(); /* 等待自键盘输入字元
switch(ch) { /* 判断输入字元为何
*/


case KEY_UP: --y; /* 判断是否"↑"键被按下
*/

break;
case KEY_DOWN: ++y; /* 判断是否"↓"键被按下
*/

break;
case KEY_RIGHT: ++x; /* 判断是否"→"键被按下
*/

break;
case KEY_LEFT: --x; /* 判断是否"←"键被按下
*/

break;
case '\r': /* 判断是否 ENTER 键被按下
*/

++y;
x=0;
break;
case '\t': /* 判断是否 TAB 键被按下
*/

x+=7;
break;
case 127: /* 判断是否 BACKSPACE 键被按下
*/

mvaddch(y,--x,' ');/* delete 一个字元
*/

break;

case 27: endwin(); /* 判断是否[ESC]键被按下
*/

exit(1); /* 结束 curses 模式
*/

/* 结束此程式
*/


default:
addch(ch); /* 如果不是特殊字元, 将此字元印
出 */

x++;
break;
}
move(y,x); /* 移动游标至现在位置
*/

} while (1);
}

void initial() /* 自定开启 curses 函式
*/

{
initscr();
cbreak();
nonl();
noecho();
intrflush(stdscr,FALSE);
keypad(stdscr,TRUE);
refresh();
}



■ 後记

学完了上述的一些命令, 相不相信您已经可以写出一个漂亮的全萤幕编辑
器了? 事实上, curses 提供的函式不下 200 个, 可是笔者认为, 一切再
复杂的函式都可以用本文提到的一些组合变化而成, 学了太多的函式, 只
是徒增自己困扰罢了. 当然, 如果您对其它函式有兴趣, 可以自行参阅
curses 说明档. ( 方法: % man curses ) 本文不过行抛砖引玉之效, 也
希望未来能陆续出现更多同学自行创作的程式.

* 任何疑问及建议, 欢迎 e-mail 至 ljh@CCCA.NCTU.edu.tw. 谢谢 ! *



注一:
请参考 /usr/share/lib/termcup
/usr/share/lib/terminfo/s/sun

注二:
1.如果是 BSD 的版本, 需使用
cc [file.c] -lcurses -ltermcap 来完成 compile.
2.计中工作站不知何故将原来的 /usr/5bin/cc 更改为 /usr/5bin/cc.org

因此, 您若想在计中工作站 compile curses 程式.需以 /usr/5bin/cc.
org
取代 /usr/5bin/cc , 否则 compile 可能发生错误.
3.较旧版的 curses 需同时引进 curses 和 termlib 这两个 library,
因此, 您必须使用 /usr/5bin/cc [file.c] -lcurses -ltermlib 来
compile.

注三:
根据笔者的经验, 上下左右方向键应可正常使用而不会发生问题, 但其它

如 PgUp,PgDn,功能键,Home,End 等特殊键, 很容易因机器, 键盘不同而无

法使用, 因此, 若您的程式须要在不同的机器上使用, 建议您只用方向键来

控制, 其它的特殊键少用为妙.
至於 PgUp,PgDn 一些特殊键的控制方法, 由於较为复杂, 有兴趣的同学可

考 tin 原始程式 curses.c 内所使用的一些方法.
用户 昵称 2002-11-01
  • 打赏
  • 举报
回复
用curses不好移植,这在嵌入式方面不好解决,也没有perl等。
相信您在网路上一定用过如 tin,elm 等工具, 这些软体有项共同的特色,
即他们能利用上下左右等方向键来控制游标的位置. 除此之外, 这些程式
的画面也较为美观. 对 Programming 有兴趣的朋友一定对此感到好奇, 也
许他能在 PC 上用 Turbo C 轻易地写出类似的程式, 然而, 但当他将相同
的程式一字不变地移到工作站上来编译时, 却出现一堆抓也抓不完的错误.
其实, 原因很简单, 他使用的函式库可能在 UNIX 上是没有定义的. 有些
在 Turbo-C 上被广泛使用的一些函式, 可能在 UNIX 上是不被定义的.

为了因应网路上各式各样的终端机形态 (terminal), UNIX 上特别发展出
一套函式库, 专门用来处理 UNIX 上游标移动及萤幕的显示. 这就是本篇
文章要为您介绍的 - curses.h 函式库. 利用这个函式库, 您也可以写出
像 elm 般利用方向键来移动光棒位置的程式. (CCCA 近来所提供的线上选
课程式, 及程式服务界面, 即是笔者利用 curses 发展而成的 )


■ curses 的历史与版本

cureses 最早是由柏克莱大学的 Bill Joy 及 Ken Arnold 所发展出来的.
当时发展此一函式库主要原因是为了提高程式对不同终端机的相容性而设
计的. 因此, 利用 curses 发展出来的程式将和您所使用的终端机无关.
也就是说, 您不必担心您的程式因为换了一部终端机而无法使用. 这对程
式设计师而言, 尤其是网路上程式的撰写, 是件相当重要的一件事.
curses之所以能对上百种以上的终端机工作, 是因为它将所有终端机的资
料, 存放在一个叫 termcap 的资料库, ( 而在第二版的 System V 系统中
, 新版的 curses 以 terminfo 取代原来的 termcap). 有了这些记录, 程
式就能够知道遇到哪一种终端机时, 须送什麽字元才能移动游标的位置,
送什麽字元才能清除整个萤幕清除. (* 注一)

另外, 本文的介绍 以 System V 的 curses 版本为主.


■ 如何在您的程式使用 curses ?

在您的 C 程式的档头将 <curses.h> include 进来.当您引进 curses.h
这个函式库後, 系统会自动将 <stdio.h> 和 <unctl.h>一并 include 进
来.另外, 在 System V 版本中, <terminfo.h> 这个函式库也将一并
include进来.

#include <curses.h>

main()
{
: :
: :
}

当然, 您的系统内必须放有 curses.h 这个函式库.


■ 如何编译(compile)

当您编辑好您的程式, 在 UNIX 提示符号下键入:

% /usr/5bin/cc [file.c] -lcurses
^^^^^^^
引进 curses.h 这个 library

或 % /usr/5bin/cc [file.c] -lcurses -ltermlib

(*注二)


■ 如何开始我的第一个 curses 程式?

在开始使用 curses 的一切命令之前, 您必须先利用 initscr()这个函式
来开启 curses 模式.

相对的, 在结束 curses 模式前 ( 通常在您结束程式前 ) 也必须以
endwin()来关闭 curses 模式.

#include <curses.h>

main()
{
initscr();
: :
: :
: :
endwin();
}

这是一般 curses 程式标准的模式.

此外, 您可以就您程式所须, 而做不同的设定. 当然, 您可以不做设定,而
只是呼叫 initscr().

您可以自己写一个函式来存放所有您所须要的设定. 平常使用时, 只要呼
叫这个函式即可启动 curses 并完成一切设定.

下面的例子, 即是笔者将平常较常用的一些设定放在一个叫 initial()的函

式内.

void initial()
{
initscr();
cbreak();
nonl();
noecho();
intrflush(stdscr,FALSE);
keypad(stdscr,TRUE);
refresh();
}


各函式分别介绍如下:

□ initscr()

initscr() 是一般 curses 程式必须先呼叫的函数, 一但这个函数
被呼叫之後, 系统将根据终端机的形态并启动 curses 模式.


□ endwin()

curses 通常以呼叫 endwin() 来结束程式. endwin() 可用来关闭
curses 模式, 或是暂时的跳离 curses 模式.如果您在程式中须要
call shell ( 如呼叫 system() 函式 ) 或是需要做 system call,
就必须先以 endwin() 暂时跳离 curses 模式. 最後再以
wrefresh() doupdate() 来重返 curses 模式.


□ cbreak()
nocbreak()

当 cbreak 模式被开启後, 除了 DELETE 或 CTRL 等仍被视为特殊
控制字元外一切输入的字元将立刻被一一读取.当处於 nocbreak 模
式时, 从键盘输入的字元将被储存在 buffer 里直到输入 RETURN
或 NEWLINE.在较旧版的 curses 须呼叫 crmode(),nocrmode() 来
取代 cbreak(),nocbreak()


□ nl()
nonl()

用来决定当输入资料时, 按下 RETURN 键是否被对应为 NEWLINE 字
元 ( 如 \n ).
而输出资料时, NEWLINE 字元是否被对应为 RETURN 和 LINDFEED
系统预设是开启的.



□ echo()
noecho()

此函式用来控制从键盘输入字元时是否将字元显示在终端机上.系统
预设是开启的.


□ intrflush(win,bf)

呼叫 intrflush 时须传入两个值:
win 为一 WINDOW 型态指标, 通常传入标准输出入萤幕 stdscr
bf 为 TRUE 或 FALSE

当 bf 为 true 时, 当输入中断字元 ( 如 break) 时, 中断的反应
将较为快速.但可能会造成萤幕的错乱.



□ keypad(win,bf)

呼叫 keypad 时须传入两个值:
win 为一 WINDOW 型态指标, 通常传入标准输出入萤幕 stdscr
bf 为 TRUE 或 FALSE

当开启 keypad 後, 可以使用键盘上的一些特殊字元, 如上下左右
等方向键, curses 会将这些特殊字元转换成 curses.h 内定义的一
些特殊键. 这些定义的特殊键通常以 KEY_ 开头.



□ refresh()

refresh() 为 curses 最常呼叫的一个函式.

curses 为了使萤幕输出入达最佳化, 当您呼叫萤幕输出函式企图改
变萤幕上的画面时, curses 并不会立刻对萤幕做改变, 而是等到
refresh() 呼叫後, 才将刚才所做的变动一次完成. 其馀的资料将
维持不变. 以尽可能送最少的字元至萤幕上. 减少萤幕重绘的时间.
如果是 initscr() 後第一次呼叫 refresh(), curses 将做清除萤
幕的工作.




■ 游标的控制

move(y,x) 将游标移动至 x,y 的位置
getyx(win,y,x) 得到目前游标的位置
(请注意! 是 y,x 而不是 &y,&x )


■ 有关清除萤幕的函式

clear()
erase() 将整个萤幕清除
(请注意配合refresh() 使用)


■ 如何在萤幕上显示字元

echochar(ch) 显示某个字元

addch(ch) 显示某个字元
mvaddch(y,x,ch) 在(x,y) 上显示某个字元
相当於呼叫 move(y,x);addch(ch);

addstr(str) 显示一串字串
mvaddstr(y,x,str) 在(x,y) 上显示一串字串
相当於呼叫 move(y,x);addstr(str);

printw(format,str) 类似 printf() , 以一定的格式输出至萤幕
mvprintw(y,x,format,str) 在(x,y) 位置上做 printw 的工作.
相当於呼叫 move(y,x);printw(format,str);



■ 如何从键盘上读取字元

getch() 从键盘读取一个字元 (注意! 传回的是
整数值)
getstr() 从键盘读取一串字元
scanw(format,&arg1,&arg2...) 如同 scanf, 从键盘读取一串字元

□例:

int ch;
char string1[80]; /* 请注意! 不可宣告为 char *string1; */
char string2[80];

echo(); /* 开启 echo 模式, 使输入立刻显示在萤幕上 */
ch=getch();
string1=getstr();
scanw("%s",string2);
mvprintw(10,10,"String1=%s",string1);
mvprintw(11,10,"String2=%s",string2);

■ 如何利用方向键

curses 将一些如方向键等特殊控制字元, 以 KEY_ 为开头定义在 curses.h

这个档案里头, 如 KEY_UP 即代表方向键的 " ↑ ". 但, 如果您想使用

curses.h 所为您定义的这些特殊键的话, 您就必须将 keypad 设定为

TRUE. 否则, 您就必须自己为所有的特殊键定义了.

curses.h 为一些特殊键的定义如下:
Linux程序设计 分卷文件共有以下2个: Linux程序设计 第4版.haozip01.zip Linux程序设计 第4版.haozip02.zip 基本信息 原书名: Beginning Linux Programming 原出版社: Wrox 作者: (英)Neil Matthew Richard Stones [作译者介绍] 译者: 陈健 宋健建 丛书名: 图灵程序设计丛书 操作系统 出版社:人民邮电出版社 ISBN:9787115228215 上架时间:2010-6-11 出版日期:2010 年6月 开本:16开 页码:642 版次:1-1 目录回到顶部↑第1章 入门 1 1.1 unix、linux和gnu简介 1 1.1.1 什么是unix 1 1.1.2 什么是linux 2 1.1.3 gnu项目和自由软件基金会 3 1.1.4 linux发行版 3 1.2 linux程序设计 4 1.2.1 linux程序 4 1.2.2 文本编辑器 5 1.2.3 c语言编译器 5 1.2.4 开发系统导引 7 1.3 获得帮助 12 1.4 小结 14 第2章 shell程序设计 15 2.1 为什么使用shell编程 15 2.2 一点哲学 16 2.3 什么是shell 16 2.4 管道和重定向 18 2.4.1 重定向输出 18 2.4.2 重定向输入 19 .2.4.3 管道 19 2.5 作为程序设计语言的shell 20 2.5.1 交互式程序 20 2.5.2 创建脚本 21 2.5.3 把脚本设置为可执行 22 2.6 shell的语法 23 2.6.1 变量 23 2.6.2 条件 27 2.6.3 控制结构 29 2.6.4 函数 39 2.6.5 命令 42 2.6.6 命令的执行 58 2.6.7 here文档 61 2.6.8 调试脚本程序 63 2.7 迈向图形化:dialog工具 63 2.8 综合应用 68 2.8.1 需求 68 2.8.2 设计 68 2.8.3 应用程序的说明 76 2.9 小结 77 第3章 文件操作 78 3.1 linux文件结构 78 3.1.1 目录 79 3.1.2 文件和设备 79 3.2 系统调用和设备驱动程序 80 3.3 库函数 81 3.4 底层文件访问 82 3.4.1 write系统调用 82 3.4.2 read系统调用 83 3.4.3 open系统调用 84 3.4.4 访问权限的初始值 85 3.4.5 其他与文件管理有关的系统调用 88 3.5 标准i/o库 91 3.5.1 fopen函数 91 3.5.2 fread函数 92 3.5.3 fwrite函数 92 3.5.4 fclose函数 92 3.5.5 fflush函数 93 3.5.6 fseek函数 93 3.5.7 fgetc、getc和getchar函数 93 3.5.8 fputc、putc和putchar函数 94 3.5.9 fgets和gets函数 94 3.6 格式化输入和输出 94 3.6.1 printf、fprintf和sprintf函数 94 3.6.2 scanf、fscanf和sscanf函数 96 3.6.3 其他流函数 98 3.6.4 文件流错误 99 3.6.5 文件流和文件描述符 99 3.7 文件和目录的维护 100 3.7.1 chmod系统调用 100 3.7.2 chown系统调用 100 3.7.3 unlink、link和symlink系统调用 100 3.7.4 mkdir和rmdir系统调用 101 3.7.5 chdir系统调用和getcwd函数 101 3.8 扫描目录 102 3.8.1 opendir函数 102 3.8.2 readdir函数 102 3.8.3 telldir函数 103 3.8.4 seekdir函数 103 3.8.5 closedir函数 103 3.9 错误处理 106 3.9.1 strerror函数 106 3.9.2 perror函数 106 3.10 /proc文件系统 107 3.11 高级主题:fcntl和mmap 110 3.11.1 fcntl系统调用 110 3.11.2 mmap函数 111 3.12 小结 113 第4章 linux环境 114 4.1 程序参数 114 4.1.1 getopt 116 4.1.2 getopt_long 118 4.2 环境变量 120 4.2.1 环境变量的用途 122 4.2.2 environ变量 122 4.3 时间和日期 123 4.4 临时文件 129 4.5 用户信息 131 4.6 主机信息 134 4.7 日志 135 4.8 资源和限制 139 4.9 小结 143 第5章 终端 144 5.1 对终端进行读写 144 5.2 与终端进行对话 149 5.3 终端驱动程序和通用终端接口 151 5.3.1 概述 151 5.3.2 硬件模型 151 5.4 termios结构 152 5.4.1 输入模式 153 5.4.2 输出模式 154 5.4.3 控制模式 155 5.4.4 本地模式 155 5.4.5 特殊控制字符 155 5.4.6 终端速度 158 5.4.7 其他函数 159 5.5 终端的输出 162 5.5.1 终端的类型 163 5.5.2 识别终端类型 163 5.5.3 使用terminfo功能标志 165 5.6 检测击键动作 170 5.7 虚拟控制台 172 5.8 伪终端 173 5.9 小结 174 第6章 使用curses函数库管理基于文本的屏幕 175 6.1 用curses函数库进行编译 175 6.2 curses术语和概念 176 6.3 屏幕 178 6.3.1 输出到屏幕 179 6.3.2 从屏幕读取 180 6.3.3 清除屏幕 180 6.3.4 移动光标 180 6.3.5 字符属性 181 6.4 键盘 183 6.4.1 键盘模式 183 6.4.2 键盘输入 184 6.5 窗口 185 6.5.1 window结构 185 6.5.2 通用函数 186 6.5.3 移动和更新窗口 187 6.5.4 优化屏幕刷新 190 6.6 子窗口 191 6.7 keypad模式 193 6.8 彩色显示 195 6.9 pad 198 6.10 cd唱片应用程序 200 6.10.1 新cd唱片应用程序的开始部分 200 6.10.2 main函数 202 6.10.3 建立菜单 203 6.10.4 操作数据库文件 204 6.10.5 查询cd数据库 209 6.11 小结 213 第7章 数据管理 214 7.1 内存管理 214 7.1.1 简单的内存分配 214 7.1.2 分配大量的内存 215 7.1.3 滥用内存 218 7.1.4 空指针 219 7.1.5 释放内存 220 7.1.6 其他内存分配函数 221 7.2 文件锁定 222 7.2.1 创建锁文件 222 7.2.2 区域锁定 225 7.2.3 锁定状态下的读写操作 227 7.2.4 文件锁的竞争 232 7.2.5 其他锁命令 236 7.2.6 死锁 236 7.3 数据库 237 7.3.1 dbm数据库 237 7.3.2 dbm例程 238 7.3.3 dbm访问函数 239 7.3.4 其他dbm函数 242 7.4 cd唱片应用程序 244 7.4.1 更新设计 244 7.4.2 使用dbm数据库的cd唱片应用程序 245 7.5 小结 262 第8章 mysql 263 8.1 安装 263 8.1.1 mysql软件包 264 8.1.2 安装后的配置 266 8.1.3 安装后的故障修复 270 8.2 mysql管理 270 8.2.1 命令 270 8.2.2 创建用户并赋予权限 274 8.2.3 密码 276 8.2.4 创建数据库 276 8.2.5 数据类型 277 8.2.6 创建表 278 8.2.7 图形化工具 280 8.3 使用c语言访问mysql数据 283 8.3.1 连接例程 283 8.3.2 错误处理 287 8.3.3 执行sql语句 288 8.3.4 更多的函数 301 8.4 cd数据库应用程序 301 8.4.1 创建表 302 8.4.2 添加数据 304 8.4.3 使用c语言访问数据 306 8.5 小结 316 第9章 开发工具 317 9.1 多个源文件带来的问题 317 9.2 make命令和makefile文件 318 9.2.1 makefile的语法 318 9.2.2 make命令的选项和参数 318 9.2.3 makefile文件中的注释 321 9.2.4 makefile文件中的宏 321 9.2.5 多个目标 323 9.2.6 内置规则 325 9.2.7 后缀和模式规则 326 9.2.8 用make管理函数库 327 9.2.9 高级主题:makefile文件和子目录 329 9.2.10 gnu make和gcc 329 9.3 源代码控制 330 9.3.1 rcs 331 9.3.2 sccs 336 9.3.3 rcs和sccs的比较 336 9.3.4 cvs 337 9.3.5 cvs的前端程序 340 9.3.6 subversion 341 9.4 编写手册页 342 9.5 发行软件 345 9.5.1 patch程序 345 9.5.2 其他软件发行工具 347 9.6 rpm软件包 349 9.6.1 使用rpm软件包文件 349 9.6.2 安装rpm软件包 350 9.6.3 创建rpm软件包 350 9.7 其他软件包格式 358 9.8 开发环境 358 9.8.1 kdevelop 358 9.8.2 其他开发环境 360 9.9 小结 360 第10章 调试 361 10.1 错误类型 361 10.2 常用调试技巧 362 10.2.1 有漏洞的程序 362 10.2.2 代码检查 364 10.2.3 取样法 365 10.2.4 程序的受控执行 367 10.3 使用gdb进行调试 368 10.3.1 启动gdb 368 10.3.2 运行一个程序 369 10.3.3 栈跟踪 369 10.3.4 检查变量 370 10.3.5 列出程序源代码 370 10.3.6 设置断点 371 10.3.7 用调试器打补丁 374 10.3.8 深入学习gdb 375 10.4 其他调试工具 375 10.4.1 lint:清理程序中的“垃圾” 376 10.4.2 函数调用工具 378 10.4.3 用prof/gprof产生执行存档 380 10.5 断言 381 10.6 内存调试 383 10.6.1 electricfence函数库 383 10.6.2 valgrind 384 10.7 小结 387 第11章 进程和信号 388 11.1 什么是进程 388 11.2 进程的结构 388 11.2.1 进程表 390 11.2.2 查看进程 390 11.2.3 系统进程 391 11.2.4 进程调度 393 11.3 启动新进程 394 11.3.1 等待一个进程 399 11.3.2 僵尸进程 401 11.3.3 输入和输出重定向 403 11.3.4 线程 404 11.4 信号 404 11.4.1 发送信号 408 11.4.2 信号集 412 11.5 小结 415 第12章 posix线程 416 12.1 什么是线程 416 12.2 线程的优点和缺点 417 12.3 第一个线程程序 418 12.4 同时执行 421 12.5 同步 423 12.5.1 用信号量进行同步 423 12.5.2 用互斥量进行同步 427 12.6 线程的属性 431 12.7 取消一个线程 435 12.8 多线程 438 12.9 小结 442 第13章 进程间通信:管道 443 13.1 什么是管道 443 13.2 进程管道 444 13.3 将输出送往popen 445 13.3.1 传递更多的数据 446 13.3.2 如何实现popen 447 13.4 pipe调用 449 13.5 父进程和子进程 451 13.5.1 管道关闭后的读操作 453 13.5.2 把管道用作标准输入和标准输出 454 13.6 命名管道:fifo 456 13.6.1 访问fifo文件 458 13.6.2 高级主题:使用fifo的客户/服务器应用程序 464 13.7 cd数据库应用程序 468 13.7.1 目标 469 13.7.2 实现 469 13.7.3 客户接口函数 472 13.7.4 服务器接口server.c 478 13.7.5 管道 481 13.7.6 对cd数据库应用程序的总结 487 13.8 小结 487 第14章 信号量、共享内存和消息队列 488 14.1 信号量 488 14.1.1 信号量的定义 489 14.1.2 一个理论性的例子 489 14.1.3 linux的信号量机制 490 14.1.4 使用信号量 492 14.2 共享内存 496 14.2.1 shmget函数 497 14.2.2 shmat函数 497 14.2.3 shmdt 498 14.2.4 shmctl 498 14.3 消息队列 502 14.3.1 msgget函数 502 14.3.2 msgsnd函数 503 14.3.3 msgrcv函数 503 14.3.4 msgctl函数 504 14.4 cd数据库应用程序 507 14.4.1 修改服务器函数 507 14.4.2 修改客户函数 509 14.5 ipc状态命令 511 14.5.1 显示信号量状态 511 14.5.2 显示共享内存状态 511 14.5.3 显示消息队列状态 511 14.6 小结 512 第15章 套接字 513 15.1 什么是套接字 513 15.2 套接字连接 513 15.2.1 套接字属性 517 15.2.2 创建套接字 519 15.2.3 套接字地址 520 15.2.4 命名套接字 520 15.2.5 创建套接字队列 521 15.2.6 接受连接 521 15.2.7 请求连接 522 15.2.8 关闭套接字 523 15.2.9 套接字通信 523 15.2.10 主机字节序和网络字节序 525 15.3 网络信息 527 15.3.1 因特网守护进程(xinetd/inetd) 531 15.3.2 套接字选项 533 15.4 多客户 534 15.4.1 select系统调用 537 15.4.2 多客户 540 15.5 数据报 543 15.6 小结 545 第16章 用gtk+进行gnome编程 546 16.1 x视窗系统简介 546 16.1.1 x服务器 547 16.1.2 x客户端 547 16.1.3 x协议 547 16.1.4 xlib库 547 16.1.5 x工具包 547 16.1.6 窗口管理器 548 16.1.7 创建gui的其他方法——平台无关的窗囗api 548 16.2 gtk+简介 549 16.2.1 glib类型系统 549 16.2.2 gtk+对象系统 550 16.2.3 gnome简介 550 16.2.4 安装gnome/gtk+开发库 551 16.3 事件、信号和回调函数 554 16.4 组装盒构件 556 16.5 gtk+构件 559 16.5.1 gtkwindow 559 16.5.2 gtkentry 560 16.5.3 gtkspinbutton 563 16.5.4 gtkbutton 565 16.5.5 gtktreeview 568 16.6 gnome构件 571 16.7 gnome菜单 572 16.8 对话框 576 16.8.1 gtkdialog 577 16.8.2 模式对话框 578 16.8.3 非模式对话框 579 16.8.4 gtkmessagedialog 580 16.9 cd数据库应用程序 581 16.10 小结 592 第17章 用qt进行kde编程 593 17.1 kde和qt简介 593 17.2 安装qt 594 17.3 信号和槽 596 17.4 qt构件 602 17.4.1 qlineedit 602 17.4.2 qt按钮 605 17.4.3 qcombobox 609 17.4.4 qlistview 613 17.5 对话框 615 17.5.1 qdialog 615 17.5.2 qmessagebox 617 17.5.3 qinputdialog 618 17.5.4 使用qmake简化makefile文件的编写 620 17.6 kde的菜单和工具栏 620 17.7 使用kde/qt编写cd数据库应用程序 624 17.7.1 主窗口 624 17.7.2 addcddialog 627 17.7.3 logondialog 629 17.7.4 main.cpp 630 17.8 小结 632 第18章 linux标准 633 18.1 c编程语言 634 18.1.1 发展历史简介 634 18.1.2 gnu编译器集 634 18.1.3 gcc选项 635 18.2 接口和lsb 636 18.2.1 lsb标准函数库 637 18.2.2 lsb用户和组 638 18.2.3 lsb系统初始化 638 18.3 文件系统层次结构标准 639 18.4 更多标准 642 18.5 小结 642 注: 仅用于学习,下载学习后请删除,请购买正版图书。
Linux程序设计 分卷文件共有以下2个: Linux程序设计 第4版.haozip01.zip Linux程序设计 第4版.haozip02.zip 基本信息 原书名: Beginning Linux Programming 原出版社: Wrox 作者: (英)Neil Matthew Richard Stones [作译者介绍] 译者: 陈健 宋健建 丛书名: 图灵程序设计丛书 操作系统 出版社:人民邮电出版社 ISBN:9787115228215 上架时间:2010-6-11 出版日期:2010 年6月 开本:16开 页码:642 版次:1-1 目录回到顶部↑第1章 入门 1 1.1 unix、linux和gnu简介 1 1.1.1 什么是unix 1 1.1.2 什么是linux 2 1.1.3 gnu项目和自由软件基金会 3 1.1.4 linux发行版 3 1.2 linux程序设计 4 1.2.1 linux程序 4 1.2.2 文本编辑器 5 1.2.3 c语言编译器 5 1.2.4 开发系统导引 7 1.3 获得帮助 12 1.4 小结 14 第2章 shell程序设计 15 2.1 为什么使用shell编程 15 2.2 一点哲学 16 2.3 什么是shell 16 2.4 管道和重定向 18 2.4.1 重定向输出 18 2.4.2 重定向输入 19 .2.4.3 管道 19 2.5 作为程序设计语言的shell 20 2.5.1 交互式程序 20 2.5.2 创建脚本 21 2.5.3 把脚本设置为可执行 22 2.6 shell的语法 23 2.6.1 变量 23 2.6.2 条件 27 2.6.3 控制结构 29 2.6.4 函数 39 2.6.5 命令 42 2.6.6 命令的执行 58 2.6.7 here文档 61 2.6.8 调试脚本程序 63 2.7 迈向图形化:dialog工具 63 2.8 综合应用 68 2.8.1 需求 68 2.8.2 设计 68 2.8.3 应用程序的说明 76 2.9 小结 77 第3章 文件操作 78 3.1 linux文件结构 78 3.1.1 目录 79 3.1.2 文件和设备 79 3.2 系统调用和设备驱动程序 80 3.3 库函数 81 3.4 底层文件访问 82 3.4.1 write系统调用 82 3.4.2 read系统调用 83 3.4.3 open系统调用 84 3.4.4 访问权限的初始值 85 3.4.5 其他与文件管理有关的系统调用 88 3.5 标准i/o库 91 3.5.1 fopen函数 91 3.5.2 fread函数 92 3.5.3 fwrite函数 92 3.5.4 fclose函数 92 3.5.5 fflush函数 93 3.5.6 fseek函数 93 3.5.7 fgetc、getc和getchar函数 93 3.5.8 fputc、putc和putchar函数 94 3.5.9 fgets和gets函数 94 3.6 格式化输入和输出 94 3.6.1 printf、fprintf和sprintf函数 94 3.6.2 scanf、fscanf和sscanf函数 96 3.6.3 其他流函数 98 3.6.4 文件流错误 99 3.6.5 文件流和文件描述符 99 3.7 文件和目录的维护 100 3.7.1 chmod系统调用 100 3.7.2 chown系统调用 100 3.7.3 unlink、link和symlink系统调用 100 3.7.4 mkdir和rmdir系统调用 101 3.7.5 chdir系统调用和getcwd函数 101 3.8 扫描目录 102 3.8.1 opendir函数 102 3.8.2 readdir函数 102 3.8.3 telldir函数 103 3.8.4 seekdir函数 103 3.8.5 closedir函数 103 3.9 错误处理 106 3.9.1 strerror函数 106 3.9.2 perror函数 106 3.10 /proc文件系统 107 3.11 高级主题:fcntl和mmap 110 3.11.1 fcntl系统调用 110 3.11.2 mmap函数 111 3.12 小结 113 第4章 linux环境 114 4.1 程序参数 114 4.1.1 getopt 116 4.1.2 getopt_long 118 4.2 环境变量 120 4.2.1 环境变量的用途 122 4.2.2 environ变量 122 4.3 时间和日期 123 4.4 临时文件 129 4.5 用户信息 131 4.6 主机信息 134 4.7 日志 135 4.8 资源和限制 139 4.9 小结 143 第5章 终端 144 5.1 对终端进行读写 144 5.2 与终端进行对话 149 5.3 终端驱动程序和通用终端接口 151 5.3.1 概述 151 5.3.2 硬件模型 151 5.4 termios结构 152 5.4.1 输入模式 153 5.4.2 输出模式 154 5.4.3 控制模式 155 5.4.4 本地模式 155 5.4.5 特殊控制字符 155 5.4.6 终端速度 158 5.4.7 其他函数 159 5.5 终端的输出 162 5.5.1 终端的类型 163 5.5.2 识别终端类型 163 5.5.3 使用terminfo功能标志 165 5.6 检测击键动作 170 5.7 虚拟控制台 172 5.8 伪终端 173 5.9 小结 174 第6章 使用curses函数库管理基于文本的屏幕 175 6.1 用curses函数库进行编译 175 6.2 curses术语和概念 176 6.3 屏幕 178 6.3.1 输出到屏幕 179 6.3.2 从屏幕读取 180 6.3.3 清除屏幕 180 6.3.4 移动光标 180 6.3.5 字符属性 181 6.4 键盘 183 6.4.1 键盘模式 183 6.4.2 键盘输入 184 6.5 窗口 185 6.5.1 window结构 185 6.5.2 通用函数 186 6.5.3 移动和更新窗口 187 6.5.4 优化屏幕刷新 190 6.6 子窗口 191 6.7 keypad模式 193 6.8 彩色显示 195 6.9 pad 198 6.10 cd唱片应用程序 200 6.10.1 新cd唱片应用程序的开始部分 200 6.10.2 main函数 202 6.10.3 建立菜单 203 6.10.4 操作数据库文件 204 6.10.5 查询cd数据库 209 6.11 小结 213 第7章 数据管理 214 7.1 内存管理 214 7.1.1 简单的内存分配 214 7.1.2 分配大量的内存 215 7.1.3 滥用内存 218 7.1.4 空指针 219 7.1.5 释放内存 220 7.1.6 其他内存分配函数 221 7.2 文件锁定 222 7.2.1 创建锁文件 222 7.2.2 区域锁定 225 7.2.3 锁定状态下的读写操作 227 7.2.4 文件锁的竞争 232 7.2.5 其他锁命令 236 7.2.6 死锁 236 7.3 数据库 237 7.3.1 dbm数据库 237 7.3.2 dbm例程 238 7.3.3 dbm访问函数 239 7.3.4 其他dbm函数 242 7.4 cd唱片应用程序 244 7.4.1 更新设计 244 7.4.2 使用dbm数据库的cd唱片应用程序 245 7.5 小结 262 第8章 mysql 263 8.1 安装 263 8.1.1 mysql软件包 264 8.1.2 安装后的配置 266 8.1.3 安装后的故障修复 270 8.2 mysql管理 270 8.2.1 命令 270 8.2.2 创建用户并赋予权限 274 8.2.3 密码 276 8.2.4 创建数据库 276 8.2.5 数据类型 277 8.2.6 创建表 278 8.2.7 图形化工具 280 8.3 使用c语言访问mysql数据 283 8.3.1 连接例程 283 8.3.2 错误处理 287 8.3.3 执行sql语句 288 8.3.4 更多的函数 301 8.4 cd数据库应用程序 301 8.4.1 创建表 302 8.4.2 添加数据 304 8.4.3 使用c语言访问数据 306 8.5 小结 316 第9章 开发工具 317 9.1 多个源文件带来的问题 317 9.2 make命令和makefile文件 318 9.2.1 makefile的语法 318 9.2.2 make命令的选项和参数 318 9.2.3 makefile文件中的注释 321 9.2.4 makefile文件中的宏 321 9.2.5 多个目标 323 9.2.6 内置规则 325 9.2.7 后缀和模式规则 326 9.2.8 用make管理函数库 327 9.2.9 高级主题:makefile文件和子目录 329 9.2.10 gnu make和gcc 329 9.3 源代码控制 330 9.3.1 rcs 331 9.3.2 sccs 336 9.3.3 rcs和sccs的比较 336 9.3.4 cvs 337 9.3.5 cvs的前端程序 340 9.3.6 subversion 341 9.4 编写手册页 342 9.5 发行软件 345 9.5.1 patch程序 345 9.5.2 其他软件发行工具 347 9.6 rpm软件包 349 9.6.1 使用rpm软件包文件 349 9.6.2 安装rpm软件包 350 9.6.3 创建rpm软件包 350 9.7 其他软件包格式 358 9.8 开发环境 358 9.8.1 kdevelop 358 9.8.2 其他开发环境 360 9.9 小结 360 第10章 调试 361 10.1 错误类型 361 10.2 常用调试技巧 362 10.2.1 有漏洞的程序 362 10.2.2 代码检查 364 10.2.3 取样法 365 10.2.4 程序的受控执行 367 10.3 使用gdb进行调试 368 10.3.1 启动gdb 368 10.3.2 运行一个程序 369 10.3.3 栈跟踪 369 10.3.4 检查变量 370 10.3.5 列出程序源代码 370 10.3.6 设置断点 371 10.3.7 用调试器打补丁 374 10.3.8 深入学习gdb 375 10.4 其他调试工具 375 10.4.1 lint:清理程序中的“垃圾” 376 10.4.2 函数调用工具 378 10.4.3 用prof/gprof产生执行存档 380 10.5 断言 381 10.6 内存调试 383 10.6.1 electricfence函数库 383 10.6.2 valgrind 384 10.7 小结 387 第11章 进程和信号 388 11.1 什么是进程 388 11.2 进程的结构 388 11.2.1 进程表 390 11.2.2 查看进程 390 11.2.3 系统进程 391 11.2.4 进程调度 393 11.3 启动新进程 394 11.3.1 等待一个进程 399 11.3.2 僵尸进程 401 11.3.3 输入和输出重定向 403 11.3.4 线程 404 11.4 信号 404 11.4.1 发送信号 408 11.4.2 信号集 412 11.5 小结 415 第12章 posix线程 416 12.1 什么是线程 416 12.2 线程的优点和缺点 417 12.3 第一个线程程序 418 12.4 同时执行 421 12.5 同步 423 12.5.1 用信号量进行同步 423 12.5.2 用互斥量进行同步 427 12.6 线程的属性 431 12.7 取消一个线程 435 12.8 多线程 438 12.9 小结 442 第13章 进程间通信:管道 443 13.1 什么是管道 443 13.2 进程管道 444 13.3 将输出送往popen 445 13.3.1 传递更多的数据 446 13.3.2 如何实现popen 447 13.4 pipe调用 449 13.5 父进程和子进程 451 13.5.1 管道关闭后的读操作 453 13.5.2 把管道用作标准输入和标准输出 454 13.6 命名管道:fifo 456 13.6.1 访问fifo文件 458 13.6.2 高级主题:使用fifo的客户/服务器应用程序 464 13.7 cd数据库应用程序 468 13.7.1 目标 469 13.7.2 实现 469 13.7.3 客户接口函数 472 13.7.4 服务器接口server.c 478 13.7.5 管道 481 13.7.6 对cd数据库应用程序的总结 487 13.8 小结 487 第14章 信号量、共享内存和消息队列 488 14.1 信号量 488 14.1.1 信号量的定义 489 14.1.2 一个理论性的例子 489 14.1.3 linux的信号量机制 490 14.1.4 使用信号量 492 14.2 共享内存 496 14.2.1 shmget函数 497 14.2.2 shmat函数 497 14.2.3 shmdt 498 14.2.4 shmctl 498 14.3 消息队列 502 14.3.1 msgget函数 502 14.3.2 msgsnd函数 503 14.3.3 msgrcv函数 503 14.3.4 msgctl函数 504 14.4 cd数据库应用程序 507 14.4.1 修改服务器函数 507 14.4.2 修改客户函数 509 14.5 ipc状态命令 511 14.5.1 显示信号量状态 511 14.5.2 显示共享内存状态 511 14.5.3 显示消息队列状态 511 14.6 小结 512 第15章 套接字 513 15.1 什么是套接字 513 15.2 套接字连接 513 15.2.1 套接字属性 517 15.2.2 创建套接字 519 15.2.3 套接字地址 520 15.2.4 命名套接字 520 15.2.5 创建套接字队列 521 15.2.6 接受连接 521 15.2.7 请求连接 522 15.2.8 关闭套接字 523 15.2.9 套接字通信 523 15.2.10 主机字节序和网络字节序 525 15.3 网络信息 527 15.3.1 因特网守护进程(xinetd/inetd) 531 15.3.2 套接字选项 533 15.4 多客户 534 15.4.1 select系统调用 537 15.4.2 多客户 540 15.5 数据报 543 15.6 小结 545 第16章 用gtk+进行gnome编程 546 16.1 x视窗系统简介 546 16.1.1 x服务器 547 16.1.2 x客户端 547 16.1.3 x协议 547 16.1.4 xlib库 547 16.1.5 x工具包 547 16.1.6 窗口管理器 548 16.1.7 创建gui的其他方法——平台无关的窗囗api 548 16.2 gtk+简介 549 16.2.1 glib类型系统 549 16.2.2 gtk+对象系统 550 16.2.3 gnome简介 550 16.2.4 安装gnome/gtk+开发库 551 16.3 事件、信号和回调函数 554 16.4 组装盒构件 556 16.5 gtk+构件 559 16.5.1 gtkwindow 559 16.5.2 gtkentry 560 16.5.3 gtkspinbutton 563 16.5.4 gtkbutton 565 16.5.5 gtktreeview 568 16.6 gnome构件 571 16.7 gnome菜单 572 16.8 对话框 576 16.8.1 gtkdialog 577 16.8.2 模式对话框 578 16.8.3 非模式对话框 579 16.8.4 gtkmessagedialog 580 16.9 cd数据库应用程序 581 16.10 小结 592 第17章 用qt进行kde编程 593 17.1 kde和qt简介 593 17.2 安装qt 594 17.3 信号和槽 596 17.4 qt构件 602 17.4.1 qlineedit 602 17.4.2 qt按钮 605 17.4.3 qcombobox 609 17.4.4 qlistview 613 17.5 对话框 615 17.5.1 qdialog 615 17.5.2 qmessagebox 617 17.5.3 qinputdialog 618 17.5.4 使用qmake简化makefile文件的编写 620 17.6 kde的菜单和工具栏 620 17.7 使用kde/qt编写cd数据库应用程序 624 17.7.1 主窗口 624 17.7.2 addcddialog 627 17.7.3 logondialog 629 17.7.4 main.cpp 630 17.8 小结 632 第18章 linux标准 633 18.1 c编程语言 634 18.1.1 发展历史简介 634 18.1.2 gnu编译器集 634 18.1.3 gcc选项 635 18.2 接口和lsb 636 18.2.1 lsb标准函数库 637 18.2.2 lsb用户和组 638 18.2.3 lsb系统初始化 638 18.3 文件系统层次结构标准 639 18.4 更多标准 642 18.5 小结 642 注: 仅用于学习,下载学习后请删除,请购买正版图书。

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧