欢迎来到个人简历网!永久域名:gerenjianli.cn (个人简历全拼+cn)
当前位置:首页 > 范文大全 > 实用文>SCO Unix下开发游戏程序Windows系统

SCO Unix下开发游戏程序Windows系统

2022-09-23 08:42:55 收藏本文 下载本文

“吃面不”通过精心收集,向本站投稿了8篇SCO Unix下开发游戏程序Windows系统,以下是小编精心整理后的SCO Unix下开发游戏程序Windows系统,希望对大家有所帮助。

SCO Unix下开发游戏程序Windows系统

篇1:SCO Unix下开发游戏程序Windows系统

SCOUnix下开发游戏程序 中国银行河南修武支行王安定 作为成熟的操作系统,Unix在重要的行业中有很广泛的应用,而在实际应用中,却存在游戏软件少、游戏开发难度大等缺点。现在虽然推出了Unix下的X窗口,但因其应用的不广泛加上介绍功能的书籍少,使新手也很

SCO Unix下开发游戏程序

中国银行河南修武支行 王安定

作为成熟的操作系统,Unix在重要的行业中有很广泛的应用。而在实际应用中,却存在游戏软件少、游戏开发难度大等缺点。现在虽然推出了Unix下的 X窗口,但因其应用的不广泛加上介绍功能的书籍少,使新手也很难入手开发自己的游戏程序。下面以自己开发的一个小游戏来介绍在Unix中游戏开发的一些基本知识。

游戏名称:《Unix下的俄罗斯方块》

开发环境:SCO Unix System V/386 Release 3.2 后经少量改动在SCO OpenServer 5.0及多种Linux环境下编译通过

开发语言:Microsoft's C compiler version 6

开发方式:Unix字符方式下用Unix自带CURSES.H图形库开发

一、开发思路

1.单人游戏时:随机产生一个方块,用户使用键盘功能键操作方块,以合适的方式放入方块队列中。当某一行方块满时就消去这一行,显示用户所消行数及得分。机器中方块下落的速度会随得分的不同而改变。

2.联机对战:基本游戏思路同单人游戏,增加了对战功能。当多人进行对战时,如某玩家一次所消的方块行数大于二行,则把所消行数随机去掉一列后传给其他用户。在其他用户的界面上可以看到从游戏界面底部一下子增加了数行。

二、游戏的界面

在Unix下,游戏的界面是一个令人头痛的问题。在字符方式下,无法完成各种精美的图形。好在我们所开发的游戏对界面要求不太高。因此,对于新手来说,我们可以用Unix本身所带的CURSES.H库中几个简单的函数来完成界面设计。

1.下面介绍几种常用的CURSES.H函数:

initscr 初始化屏幕(必须有)

clear()、wclear() 清屏

newwin() 开一个新窗口

box() 在窗口边画一个框

mvprintw(int x,int y,char *,...)类似于printf,不同之处是在窗口的 (x,y)位置显示信息

mvscanw(int,int,char *,...)在指定位置读信息

mvwaddstr() 在指定窗口的指定位置显示字符串

wstandout() 反相显示开始

wstandend() 反相显示结束

cbreak() 立即显示所接收到的字符

nocbreak() 接收到一个换行符后才显示所接收到的字符

echo() 显示所输入的字符

noecho() 不显示所输入的字符

delwin() 删除一个窗口

touchwin() 击活一个窗口

wrefresh() 刷新一个窗口

beep() 响铃

keypad() 功能键开关

wgetch() 在窗口中读一个字符输入

wmove() 在窗口中移动光标

endwin() 结束图形方式(必须有)

2.图形方式光标移动键定义如下:

KEY_DOWN  0402向下键

KEY_UP  0403 向上键

KEY_LEFT  0404向左键

KEY_RIGHT  0405向右键

三、随机方块的产生

在俄罗斯方块中,共有19种不同的方块类型,要随机产生不同的方块可以用以下两个函数来实现:

1.定义随机数发生器:根据时间函数的返回值不同而产生不同的随机数。

#define randomize() srand((unsigned)time(NULL))

2.定义随机数:该函数能产生介于0到num-1之间的所有数。

#define random(num) (rand()%num)

定义上面两函数后便可用下面的函数rand_block()产生一个随机数:

/* 程序功能:随机产生一个介于0-19之间的数;入口参数:无

返回值:flag */

int rand_block()

{

int flag;

randomize();

flag=rand(19);

return(flag);

}

四、游戏的控制-

---1.终端控制

Unix中终端的输入输出控制用的是ioctl()系统调用。原型如下:

#include

int ioctl(int fd,int request,struct termio *argu)

fd为文件描述字,与一台终端相对应;request 是一个命令,我们用到的命令有TCGETA和TCSETA两个,作用分别是将fd所对应的终端信息存入termio结构和将fd所对应的终端设定为termio所描述的形式。 argu是一个指向 termio 类型的指针。

程序中,对终端的控制主要是对中断键的处理和对输入模式的不同切换。对中断键的处理主要是用到termio指针中c_clearcase/“ target=”_blank“ >cc数组中的控制。下面的一段程序便可保存起当前终端信息,忽略中断键(置其值为255),然后重设当前终端。

struct termio *old_tbuf,tbuf;

ioctl(0,TCGETA,&old_tbuf); /* 取当前终端信息 */

tbuf=old_tbuf; /* 保存终端信息 */

tbuf.c_cc[VINTR]=255; /* DEL */

tbuf.c_cc[VQUIT]=255;   /* CTRL- */

tbuf.c_cc[VERASE]=255;   /* CTRL_h */

tbuf.c_cc[VKILL]=255;  /* CTRL-u */

tbuf.c_cc[VEOL]=255;  /* CTRL-d */

tbuf.c_cc[VSWTCH]=255;  /* CTRL-z */

tbuf.c_cc[VSTOP]=255; /* CTRL-s */

tbuf.c_cc[VSTART]=255;  /* CTRL-q */

ioctl(0,TCSETA,&tbuf);/* 设置当前终端 */

2.下落动画控制

在Unix系统中,有两种输入模式可供选择:一种是标准模式,一种是原始模式。在标准模式下,输入字符存储在输入队列的缓冲区中,直到读入换行符或是EOT(^-d)字符后才将所有数据一次输出;在原始模式下,字符一键入就立即输出,没有缓冲区。系统默认的是标准模式,但在游戏中,我们要不断在两种模式间切换,完成切换要用到tbuf.c_lflag[ICANON]来完成,如果设为ON,则默认为标准输入模式,否则为原始模式。

在游戏中,我们要求每一个方块在产生后,便能自动地下落。实现这个动画效果,要用到原始模式下的两个重要标志:VMIN和 VTIME,它们分别表示read系统调用返回前所需读取的最少字数和最长时间,

要控制方块自动下落,可用下面两句:

tbuf.c_cc[VMIN]=0;

tbuf.c_cc[VTIME]=1;

ioctl(0,TCSETA,&tbuf);

功能:read在收到一个字符或未收到字符但定时一秒时返回

3.速度控制

在俄罗斯方块中,游戏的可玩性还在于速度在不断的变化中。在这里,我们就要用到间隔化技术。所谓间隔化技术,就是在指定了开始位置和结束位置的情况下,确定游戏间隔步骤过程的技术。我们可以用一个空循环来实现方块因得分不同而使每一次下落的速度不同。定义速度常数 SPEED为十万(可根据机器速度不同自行定义),然后根据不同的行分而改变循环次数,如下边所写(score为用户当前得分):

if(score<10000) for(i=0;i else for(i=0;i五、游戏操作的实现 在游戏中,对方块的操作主要是由几个光标功能键来控制,功能定义如下:

1、↑ 翻转

2、↓ 速降

3、← 左移

4、→ 右移 5、Esc结束 6、c 刷屏

7、p 暂停

由于在图形方式下不能完成对方块的各种操作,这就使我们要找到合适的函数来定义各功能键。在Unix中,↑↓ ← →各键的引导字符是27,对游戏操作的实现也就是改变方块显示位置及显示不同方块类型的转换。当然还可以定义一些秘键:减速、增速、使对手增行、清空自己所有行等。

六、游戏的记录

1.记录结构的定义:

struct user_data

{

char name[8]; /* 用户姓名 */

int score; /* 用户最高得分 */

int line; /* 最高分时所消除方块行数 */

}

2.记录文件的几种操作:

在程序中要用到记录文件来存放用户记录,本游戏中记录文件名为user.dat,以下是几种文件的常用操作。在操作前要先定义一个FILE类型的指针 (FILE *fp):

fopen() 打开文件

fscanf() 从文件中读数据

access() 检测文件存在否及文件属性

creat() 建立新文件

fseek() 文件定位

fprintf() 写数据到文件中

fclose() 关闭文件

用下面的一段程序便可测试用户记录文件存在否。如不存在,则建立新的文件,并写一个空的入门成绩到用户记录文件中。游戏中你可用这几个函数来往记录文件中追加新的记录或改写记录。

if(access(“user.dat”,00)) /* 检测有无用户记录文件 */

{

creat(“user.dat“,0644); /* 如无文件则建立新的文件 */

fp=fopen(“user.dat”,“r+“); /* 写入一个空记录 */

fprintf(fp,“入门成绩 3000   20n”);fclose(fp);

七、联机对战的实现

联机对战的主要思路是在各个不同用户间传递信息。在Unix 下,我们可以用消息队列来进行数据的传递。消息队列能将格式化的数据送往任意的进程,所用到的有关系统调用如下。

1.建构一个新的消息队列或取得一个现存的消息队列的标识符:

#include “sys/types.h“

#include “sys/ipc.h”

#include “sys/msg.h“

int msgget(key_t key,int flags)

key是指消息队列的名字,它的值若是IPC_PRIVATE(值为零),指该消息队列为该进程专用,否则表示为一个以上的进程所共用。

flags用于表示消息队列的存取权限。

2.取得或修改已存在的消息队列的属性:

int msgctl(int msgid,int cmd,struct msqid_ds *mbuf)

msgid是消息队列的标识符。

cmd为符号常数: IPC_STAT(拷贝消息队列到MBUF所指向的地址)、IPC_SET(设定消息队列的存取权限)、IPC_RMID(删除消息队列)。

3.发送和接收消息:

int msgsnd(int msgid,const void *msgp,size_t msgsz,int msgflg)

int msgrcv(int msgid,void *msgp,size_t msgsz,long msgtyp,int msgflg)

msgid:消息队列的标识符。

msgp:消息缓冲区,暂时存储发送与接收的消息。

msgsz:消息的大小。

msgtyp:消息的类型。

msgflg:用来指明核心程序在队列没有数据的状况下,所应采取的行动。

八、游戏中的各种标志位

最重要的标志位是位置方块标志:定义一个二维数组,对应于游戏中方块的区域大小。如play[25][80],然后根据该标志为0或1来判断该位置有无方块,其他标志都是根据这个标志来工作的。所用到的标志还有游戏左右界标志、消行标志、增行标志(联机对战中)、能否移动标志、游戏结束标志等。

九、其他功能

游戏主体内容建立后,还有一些功能需要用户自己来完成。如清除上次显示方块、显示下一方块提示信息、无敌作弊法、记录排序、游戏速度的精确计算、增删行函数、速降函数、方块变换等,还需要进一步完善才成为完整的程序。

附例程:从标准输入读字符,如为光标移动键返回该键值,否则返回该字符值。

int mygetch()

{

int i;

char c;

struct termio *old_tbuf,tbuf;

ioctl(0,TCGETA,&old_tbuf);/* 取当前终端信息 */

tbuf=old_tbuf;

tbuf.c_lflag&=~ICANON; /* 设为原始模式 */

tbuf.c_cc[VNUM]=1;/* 设最少输入一个字符 */

tbuf.c_cc[VTIME]=0;/* 等待时间为0 */

ioctl(0,TCSETA,&tbuf);

i=read(0,&c,1);

if(c==27){/* 如为27则为光标键前导码 */

read(0,&c,1);read(0,&c,1);

switch(c){

case ‘A':return(56);break;/* UP */

case ‘B':return(50);break;/* DOWN */

case ‘C':return(54);break;/* RIGHT */

case ‘D':return(52);break;/* LEFT */

case 27:return(27);break;/* ESC */

}

ioctl(0,TCSETA,&old_tbuf);

return(c);

}

【发表回复】【查看CU论坛原帖】【添加到收藏夹】【关闭】

原文转自:www.ltesting.net

篇2:AWK程序Windows系统

2、AWK部份内置变量: FILENAME 当前文件名 FNR当前文件的总共记录数 FS输入的字段分隔符 NF当前记录的字段数目 NR到目前为止,读入的记录数目 OFS输出文件的字段分隔符 ORS输出文件的记录分隔符 RS输入记录的分隔符 3、/ETC/RESOLV.conf文件是SCO的域名解释

2、AWK部份内置变量:

FILENAME 当前文件名

FNR当前文件的总共记录数

FS输入的字段分隔符

NF当前记录的字段数目

NR到目前为止,读入的记录数目

OFS输出文件的字段分隔符

ORS输出文件的记录分隔符

RS输入记录的分隔符

3、/ETC/RESOLV.conf文件是SCO的域名解释配置文件,格式:NAMESERVER IP地址,另外,必须在用户

的.PROFILE文件里面加上一句,HOSTRESORDER=”local nis bind“;export HOSTRESORDER,这句话,是

设置在主机解释域名的搜索顺序,先是本机,然后是NIS,再是DNS,

4、在AWK中,数组的下标可以是数字,也可以是字符串,如,arr[1]或者是arr[sales]。

5、split(string,arr,fs)函数可以把字符串STRING以FS为分隔符分解成为一个个的数组元素,放到ARR中。

6、delete arr [subscript]删除数组ARR[subscript]元素。

7、在AWK中,for( i in arr) statements是一个FOR循环。

8、if (expression) statement1 [else statment2];

9、expression1

while(expression2)

{statement1;expression3}

10、do {statement} while (expression)

11、NEXT是强迫AWK读入下一个记录,进行处理

12、在AWK中,PRINT或者是PRINTF输出表达式中如果有关系比较符号(如大于>),则需要把PRINT或者是

PRINTF用圆括号括起来,如print $0,($2 > $3)是打印记录,随后是1或者0;但是如果是print $0,$2 >$3则

是打印整条记录,第二个字段到文件名为$3的文件中去。

13、在AWK中,可以用CLOSE关闭一个文件(CLOSE(filename));关闭一个管道(close(command_line));

14、在AWK中,输入可以用以下几种方式:

< filename

getline

getline 

getline x 

command | getline

command | getline x

如果GETLINE正确,则返回1,文件结束返回0,出错返回-1,

15、在AWK中的一些字符处理函数:

gsub(r,s,t)以字符S替换满足正则表达式R的字符串T中R。

index(s,t)在字符串S中查找字符串T第一次出现的位置,没有则返回零。

legnth(s)测字符串S的长度。

match(s,re)在字符串S中查找正则表达式RE的第一次出现的位置,如果有则返回,同时置RSTART为

该数字;如果没有则返回0。

split(string,arr,fs)见前面。

sprintf(format,expression,expression1,...)

sub(r,s,t)以s替换字符串T中的R。

substr(s,p)取字符中S从位置P开始的字符串。

substr(s,p,n)取字符中S从位置P开始的N个字符。

tolower(s)

toupper(s)

在字符处理函数中,如果被处理字符串为空,则缺省值是$0。

16、在AWK中,还可以用system(command_line)运行系统命令。

17、还可以自定义函数:

function name(parameter_list){statements}其中,parameter_list是以逗号分隔的变量组合。在函数

中如果变量少于定义的数字,则少的设为空;多的则被忽略。为了在函数中有返回值,必须在函数中有一

句return expression

18、在AW中,如果要强制转换一个变量的类型,则需要number ”“是强制number变量为字符型变量。

19、在AWK中,把一个字符型变量强制转换成数值型,则需要string+0。

20、AWK程序成功执行返回0,否则返回>0

21、在正则表达式中,”,[ t]* | [ t]+“表示以,号和(或者)与空格空行的记录,或者是完全就是空格或者

空行。在正则表达式中*代表任意字符,+代表前缀字符的一个或者任意多个的组合。

studio99 回复于:-08-27 09:31:06找了你好久了

yychs 回复于:2003-08-24 17:10:52very good.

原文转自:www.ltesting.net

篇3:UNIX开发系统程序调试例举Windows系统

来看看在哪些情况下需要对程序进行调试, 第一种情况(这是大多数用户都会碰到的),程序在运行过程中忽然跳了出来,屏幕上显示一个xxxx-coredumped消息, 然后Shell提示符就又显示出来了,其中xxxx表示出错原因。这种情况的出现一般是系统核心认为进程的执

来看看在哪些情况下需要对程序进行调试。

第一种情况(这是大多数用户都会碰到的),程序在运行过程中忽然跳了出来,屏幕上显示一个xxxx-core dumped消息,

然后Shell提示符就又显示出来了,其中xxxx表示出错原因。这种情况的出现一般是系统核心认为进程的执行出现了异常,

如进程试图去访问一块不允许它访问的存储区域(Memory Fault,Segmentation Fault);或者扫描某个无终止符的字符串

(Bus Error);或者浮点运算溢出或被0除(Arithmetic Exception),等等。此时操作系统会把进程当时的内存映象写到

当前目录下的一个名叫core的文件中。这种情况下我们可以使用sdb来检查此core文件,以决定出错的地点以及程序执行

的状态,如函数间的调用关系、变量的值,等等。

第二种情况,程序可能并没有什么异常行为,但就是怎么也得不到正确的输出结果。这时需要在该进程运行过程中对之进

行调试。这种情况下我们可以使用sdb逐条语句地跟踪程序的执行过程,并在执行过程中检查有关变量的值的变化情况。

上述两种情况并不是绝然分开的。实际上它们可以结合在一起使用。例如,当我们利用core文件对某个已终止的进程进行

调试时,可以在sdb中重新启动相应程序的运行,然后对语句的执行进行一些控制。这样我们就能够知道在出现异常之前哪

个程序到底是如何动作的。

为了使sdb能够很好地对程序进行调试,在编译程序时应指示编译程序和链接程序在目标代码中加入调试用的各种信息,如

程序中的变量名、函数名及其在源程序中的行号等。我们知道,使用-g选项可以完成这一点。如我们可以用如下命令编译

前一章给出的有毛病的程序代码:

$clearcase/” target=“_blank” >cc-o myprog myprog.c myfunc.c

myprog.c:

myfunc.c:

$ ls -l myprog

-rwx-xr-x 1 yxz users 4224 Sep 1 10:17 myprog

$ cc -g -o myprog myprog.c myfunc.c

myprog.c

myfunc.c

$ ls -l myprog

total 26

-rwxr-xr-x 1 yxz users 5404 Sep 1 10:21 myprog

$

这时我们会发现,新生成的myprog比不带-g 选项生成的myprog要大的多。故在程序调试完成之后应将可执行程序中的调试

用信息去掉。最简单的方法当然是使用不带-g 选项的cc命令重新编译一遍。另外UNIX系统提供了另外一个名为strip的工具,

使用此命令也可以将程序中的调试信息去掉。

现在我们可以试着运行一下那个有问题的程序myprog。在shell提示符下输入:

$ myprog 1 111

Arithmetic Exception -core dumped

$

我们看到,程序由于异常而推出了,并且在当前目录下将生成一个名为core 的文件。这个文件有时非常庞大。在文件系统

的维护中,有一条就是要定期找出各目录下的core 文件并将其删除掉。

发生此种情况时可以使用sdb来对之进行调试。输入:

$ sdb myprog

即可进入sdb调试程序。

sdb将接受三个参数:

待调试的可执行文件名;

待调试的core文件名,一般缺省是core;

由冒号分隔的一个目录表,sdb将在这些目录表中去查找有关的源文件。此目录表的缺省设置是当前目录

有时当前目录下的core文件可能并不是待调试的程序的core 文件,此时用这个core 文件进行调试就是不合适的了。为防止

这一点,可在命令行中指定第二个参数为减号(-),如下所示:

$ sdb myprog -

这里的“-”告诉sdb忽略当前目录下的core文件。

第三种情况,我们试用对活动过程(正在运行的进程)进行调试的情况。例如,假定某个程序正在后台运行,但我们注意到

该程序的某些部分执行起来非常慢,这时我们可以在不杀死这个进程的情况下对之进行调试:

$ sdb /proc/1111

这里1111为待调试进程的进程号,用户可以用PS命令得到。系统在/proc目录下用文件的形式保存了每一个活动进程的信息,

而文件名正好就是相应的进程号。

指定的进程将在执行时遇到第一个系统调用或调用sdb后收到某个软中断信号时暂停其运行,我们就可以在sdb中检查变量的值、

设置断点、恢复执行,等等。在退出sdb时,控制又返回程序,执行进程又从其原停止的地方继续执行。

第四种情况,一般情况下当被调试的活动进程在收到某个软中断信号时sdb会停止该进程。为了防止这一点,可以使用-s 选项。

例如:

$ sdb -s 14 myprog

将告诉sdb不要因为软中断信号14(闹钟报警信号)而使进程的执行停止。此时该信号被传给相应进程。在程序接收并处理多个

软中断信号的情况下,可以使用多个-s选项。

在sdb命令行中还有其他一些选项,对此我们不再一一列举,读者可以参考命令帮助。

在使用上述方法之一进入sdb之后,便可以进行在前一节中提到的各种操作,如显示或设置变量值、函数调用关系、控制语句的

执行等。下一节我们将详细讨论完成这些操作的方法。

sdb命令的使用

同我们前面介绍过的mail,ftp一类工具类似,sdb也是一个命令解释程序。也就是说,用户在sdb提示符(一个星号*)下输入sdb

能够识别的命令,sdb将根据被调试的程序的具体情况给出响应。

例如,在运行myprog出错,生成core文件之后进入sdb时,sdb将给出如下的响应:

$ sdb myprog

12: return ((100/atoi(ValueInput))? TESTOK:! TESTOK);

*

sdb给出来的实际上是程序出错所在的函数,在源程序文件中的行号以及出错那一行的语句。

在sdb的使用中要注意三个“当前”概念:

(1)当前文件 即当前将要被执行的语句所在的那个源程序文件

(2)当前函数 即当前将要被执行的语句所在的那个函数

(3)当前行 这个概念只有在编译时加入-g选项才会有,它指的是将要被执行的那条语句,

与当前行相应,有一个行号的概念。

它指的是每条语句在程序中位于第几行。注意行号是从文件头开始计算的,第一行的行号为1,空白行和注释也包括在内。

在用core文件进行调试时,当前行和当前函数分别被设成是程序出错时所执行的那条语句所在地行和函数(如同上面显示出来

的那样)。但如果在编译时未加-g选项,显示出来的将只有函数名和函数的地址了。

在对活动进程进行排错时,sdb将把当前函数和当前行分别设成是main函数和main()函数的第一个可执行的语句行。

不论是哪种情况,sdb都将显示出*提示符。在此提示符之下我们可以输入各种sdb命令,以控制程序的执行或观察变量的变化

情况,等等。在下面的几个小节中我们将分别详细讨论这些问题。

源程序的显示和搜索

程序出错一般来说不只是出错的那条语句本身造成的。事实上出现错误经常是前面或相关的代码执行了不正确的操作或少了某

些必要的处理。因此调试过程中经常要观察一下源程序中的语句,或者在程序中搜索某个符号出现在什么地方。其中字符串的

搜索功能同vi基本上是相同的,而文件的显示则同另外一个我们没有具体讨论的编辑器ed类似。下面我们将具体介绍这些命令。

1.源程序的显示

在用core进入sdb之后,在*提示符后输入w命令,该命令指示sdb显示源程序中的当前行为中心的前后10行的内容并保持当前行

不变:

* w

7:int

8: TestInput(char * ValueInput)

9: {while ( * ValueInput)

10: if (! isdigit( * ValueInput)) return (! TESTOK);

11: else ????ValueInput++;

12: return ((100/atoi(ValueInput))? TESTOK:! TESTOK);

13: }

*

我们看到,在进入sdb时,当前行是第12行,以该行为中心的10行内容正好就是上面所显示出来的。其他可以显示源程序语

句的sdb命令如下:

P 显示当前行

l 显示对应于当前指令的那条语句

Z 显示当前行开始的下面10条语句

Ctrl+D 显示当前行之后(不包括当前行)的第10条语句

n 显示第n条语句,这里n是一个数

注意这些命令显示出的是源程序语句还是汇编语句(后面我们将要介绍)取决于最近一次显示出的是什么。

2.改变当前行

在用户显示语句时,当前行也会相应地发生变化。例如,Z命令将使当前行向程序尾移动9行,而Ctrl+D则使当前行向后移

动10行。

在使用数字来显示某行语句时将使该行语句成为当前行。而在*提示符之后按一下回车,当前行将下移一行。例如,接着上面

的例子,输入:

* 8p

8: TEstInput(char * ValueInput)

* 回车

9: { while ( * ValueInput)}

*

这里8p实际上是两条命令的组合。它使当前行移至源文件的第八行,然后再显示出新的当前行。按回车键将使当前行后移一行。

3.改变当前源文件

在vi中我们可以用e命令对另外某个文件进行编辑。sdb也提供了e命令,可以用此命令来改变当前文件,如:

* e myprog.c

current file is now myprog.c

* 8p

8: main(int argc,char * argv[])

*

我们看到,当前文件改变之后,sdb将第一行设为是当前行。如果此文件的第一行是个函数,那么该函数便成为当前函数。

否则将临时出现没有当前函数的情况。

在上一节中,我们介绍过在命令行中可以指定源文件搜索目录名列表(缺省情况为当前目录)。如果某个文件不在此搜索

目录中,则可以用e命令将其加入:

* e Another SourceDir

这里Another SourceDir是一个目录名。如果要显示该目录下的某个文件,只需要输入:

* e FileName.c

当然直接使用:

* e Another SourceDir/FileName.c

也能达到同样的效果。

使用:

* e FunctionName

将使包含函数FunctionName的文件名成为当前文件,而当前函数不言而喻将成为FunctionName。当前行则理所当然的是该

函数的第一行。同一程序中函数名在各模块中的唯一性保证了这一点是能够成功的,但如果包含指定函数的文件不在当前

搜索目录列表中,则必须用e命令将其加入。

4.字符串的搜索

在vi中,我们可以在命令方式下使用“/“或者“?”命令,从当前位置向后或者向前搜索某个字符串,在sdb中也同样可

以完成这一点。使用这两个命令我们可以查找源程序中某个或某类符号的出现。之所以说某类,是因为我们可以用正规表

达式来指定待搜索的串(也即在搜索串中可以使用*,?,[,],-,^这类特殊字符)。

例如,为了查找myprog.c中argv出现在那些行上,可输入:

* /argv/

8: main(ini argc,char * argv[])

sdb将从当前行开始向文件尾搜索,到达文件尾之后又从文件头开始直至搜索到某个匹配的串或到达当前行为止。

与/相反,?命令将从当前行向文件头方向搜索,因此如果我们将上述/argv/换成:

* ? argv?

14: printf(“The %dth value' %s'tis BAD! n”,i,argv[i]);

*

所得的结果一般是不同的。

/或?命令之后的/或?并不是必须的。另外如果要在同一方向上继续搜索上次搜索过的串,只需要直接输入/或者?即可。

BOCAIX 回复于:-11-30 11:56:48十分感谢!!!

Red_Crow 回复于:2004-11-30 15:59:49:em02: !谢了。

原文转自:www.ltesting.net

篇4:Unix系列shell程序编写(下)Windows系统

[code:1:0fdddfdb40] Until语句 While语句中,只要某条件为真,则重复执行循环代码,until语句正好同while相反,该语句使循环代码重复执行,直到遇到某一条件为真才停止, Until语句的结构如下: untilcommand do command command …… done 可以用until语句

[code:1:0fdddfdb40]

Until语句

While语句中,只要某条件为真,则重复执行循环代码,until语句正好同while相反,该语句使循环代码重复执行,直到遇到某一条件为真才停止。

Until语句的结构如下:

until command

do

command

command

… …

done

可以用until语句替换上面备份程序的while语句,完成同样的功能:

until [ $ANS != Y -a $ANS != y ]

for 循环

在介绍for循环之前,我们要学个非常有用的unix命令:shift。我们知道,对于位置变量或命令行参数,其个数必须是确定的,或者当Shell程序不知道其个数时,可以把所有参数一起赋值给变量$*。若用户要求Shell在不知道位置变量个数的情况下,还能逐个的把参数一一处理,也就是在$1后为$2,在$2后面为$3等。在 shift命令执行前变量$1的值在shift命令执行后就不可用了。

示例如下:

#测试shift命令(x_shift.sh)

until [ $# -eq 0 ]

do

echo “第一个参数为: $1 参数个数为: $#”

shift

done

执行以上程序x_shift.sh:

$./x_shift.sh 1 2 3 4

结果显示如下:

第一个参数为: 1 参数个数为: 3

第一个参数为: 2 参数个数为: 2

第一个参数为: 3 参数个数为: 1

第一个参数为: 4 参数个数为: 0

从上可知shift命令每执行一次,变量的个数($#)减一,而变量值提前一位,下面代码用until和shift命令计算所有命令行参数的和。

#shift上档命令的应用(x_shift2.sh)

if [ $# -eq 0 ]

then

echo “Usage:x_shift2.sh 参数”

exit 1

fi

sum=0

until [ $# -eq 0 ]

do

sum=`expr $sum + $1`

shift

done

echo “sum is: $sum”

执行上述程序:

$x_shift2.sh 10 20 15

其显示结果为:

45

shift命令还有另外一个重要用途,Bsh定义了9个位置变量,从$1到$9,这并不意味着用户在命令行只能使用9个参数,借助shift命令可以访问多于9个的参数。

Shift命令一次移动参数的个数由其所带的参数指定。例如当shell程序处理完前九个命令行参数后,可以使用shift 9命令把$10移到$1。

在熟悉了shift命令后,我们一起看看,Bsh程序中非常有用的for循环语句,这种循环同上面说的while和until循环不同,for语句中的循环是否执行并不由某个条件的真和假来决定,决定for循环是否继续的条件是参数表中是否还有未处理的参数。

For语句的结构如下:

for variable in arg1 arg2 … argn

do

command

command

… …

done

下面是for循环的简单例子:

for LETTER in a b c d

do

echo $LETTER

done

程序执行结果如下:

a

b

c

d

在上面计算参数和的例子中,我们可以用for循环,实现如下:

#测试 for 程序(x_for.sh)

if [ $# -eq 0 ]

then

echo “Usage:x_for.sh 参数… …”

exit 1

fi

sum=0

for I in $*

do

sum=`expr $sum + $I`

done

echo “sum is: $sum”

中断循环指令

在程序循环语句中,我们有时候希望遇到某中情况时候结束本次循环执行下次循环或结束这个循环,这就涉及到两条语句:continue和break。continue命令可使程序忽略其后循环体中的其他指令,直接进行下次循环,而break命令则立刻结束循环,执行循环体后面的的语句。

#测试continue

I=1

while [ $I -lt 10 ]

do

if [ $I -eq 3 ]

then

continue

fi

if [ $I -eq 7 ]

then

break

fi

echo “$Ic”

done

执行上面程序,结果如下:

12456789

与或结构

使用与/或结构有条件的执行命令

Shell程序中可以使用多种不同的方法完成相同的功能,例如until和while语句就可以完成相同的功能,同样,除了if-then-else结构可以使命令有条件的执行外,$$和||操作符也能完成上述功能。在C语言中这两个操作符分别表示逻辑与和逻辑或操作。在Bourne Shell中,用&&连接两条命令的含义只有前面一条命令成功执行了,后面的命令才会执行。

&&操作的形式为:

command && command

例如语句:

rm $TEMPDIR/* && echo “Files suclearcase/” target=“_blank” >ccessfully removed“

只有rm命令成功执行以后,才会执行echo命令。若用if-then语句实现上述功能,形式为:

if rm $TEMPDIR/*

then

echo ”Files successfully removed“

fi

相反,用||连接两条命令的含义为只有第一条命令执行失败才执行第二条命令,例如:

rm $TEMPDIR/* || echo ”File were not removed“

上面语句的等价形式为:

if rm $TEMPDIR/*

then

:

else

echo ”Files were not removed“

fi

这两种操作符可以联合使用,如在下面的命令行中,只有command1和command2执行成功后,command3才会执行:

command1 && command2 && command3

下面的命令行表示只有command1成功执行,command2不成功执行时,才会执行command3。

&&和||操作符可以简化命令条件执行的格式,但一般只用于一条命令的条件执行。如果许多命令都使用这两个操作符,那么整个程序的可读性将变的很差,所以在多条命令的条件执行时,最好采用可读性好的if语句。

函数

现在我们介绍Shell程序中的函数部分,基本上任何高级语言都支持函数这个东西,能让我们胜好多事情的东西,至少省的频繁的敲击相同的东西,好了come on

Shell程序中的函数

函数又叫做子程序,可以在程序中的任何地方被调用,其格式如下:

函数名字()

{

command

... ...

command;

}

Shell程序的任何地方都可以用命令 ”函数名字“ 调用,使用函数的好处有两点,一点是使用函数可以把一个复杂的程序化为多个模块,易于管理,符合结构化程序的设计思想,另一个好处是代码的重用。

Shell函数和Shel程序比较相似,它们的区别在于Shell程序在子Shell中运行,而Shell函数在当前Shell中运行。因此,在当前Shell中可以看到Shell函数对变量的修改。在任何Shell中都可以定义函数,包括交互式Shell。

例如:

$dir() {ls -l;}

结果是我们在$后面打dir,其显示结果同ls -l的作用是相同的。该dir函数将一直保留到用户从系统退出,或执行了如下所示的unset命令:

$unset dir

下面的例子说明了函数还可以接受位置参数:

$dir(){_

>echo ”permission ln owner group file sz last access

>ls -l $*;

>}

运行 dir a* 看产生什么结果

参数a*传递到dir函数中并且代替了$*

通常Shell程序将在子Shell中执行,该程序对变量的改变只在子Shell中有效而在当前Shell中无效。“.”命令可以使Shell程序在当前Shell中执行。用户可以在当前Shell中定义函数和对变量赋值。通常用下面命令来重新初使化.profile对Shell环境的设置。

$ . .profile

由于看到这部分相对简单,我们还是顺便说说trap好了

使用trap命令进行例外处理

用户编写程序在程序运行时可能会发生一些例外情况,比如执行该程序的用户按中断键或使用kill命令,或者控制终端突然与系统断开等。unix系统中的上述情况会使系统向进程发一个信号,通常情况下该信号使进程终止运行。有时侯用户希望进程在接到终止信号时进行一些特殊的操作。若进程在运行时产生一些临时文件,又因接受到的信号而终止。那么该进程产生的临时文件将保留下来。在bsh中,用户可以使用trap命令修改进程接收到终止信号时进行的默认操作。

trap命令格式如下:

trap command_string signals

多数系统中共有15种发给进程的信号,默认情况下大多数信号都会使程序终止。用户最好查阅自己系统的文挡,看看本系统内使用的信号种类。除了信号为9(真正的kill信号)不能使用trap命令外,其他信号所带来的操作都可以用trap命令进行指定。下面是trap命令中经常使用的几种信号:

信号 功能

1  挂起

2 操作中断

15 软终止(kill信号)

若命令串中包含不只一条命令,必须使用引号将整个命令括起来,具体是单引号还是双引号,由用户是否需要变量替换决定。“ ”替换,' '不替换。

使用下面trap命令可以使程序在接收到挂起、中断或kill信号时,首先把临时文件删除,然后退出:

trap “rm $TEMPDIR/* $$;exit” 1 2 15

在上面例子中,当Shell读取trap命令时,首先对$TEMPDIR和$$进行变量替换,替换之后的命令串将被保存在trap表中,若上例中trap命令使用单引号时,trap命令执行时候,不进行变量替换,而把命令串 rm $TEMPDIR/* $$;exit 放到trap表中,当检测到信号时,程序解释执行trap表中的命令串,此时进行变量替换,

前面变量$TEMPDIR和$$的值为执行trap指令时候的值,后一种情况中变量的值为程序接收到信号时候的值,所以 “、'一定要区分仔细。

下面命令的含义为用户按二次中断键后,程序才终止:

trap 'trap 2' 2

一般trap命令中的命令串中几乎都包含exit语句,上面rm的例子若无exit语句,接收到信号rm命令执行完后程序将挂起。但有时用户也需要程序在接到信号后挂起,例如当终端和系统断开后,用户发出挂起信号,并执行空命令,如下:

trap : 1

若用户想取消前trap指令设置的命令串,可以再执行trap命令,在命令中不指定命令串表示接收到信号后进行默认的操作,命令如下:

trap 1

规范Shell

获取UNIX类型的选项:

unix有一个优点就是标准UNIX命令在执行时都具有相同的命令行格式:

command -options parameters

如果在执行Shell程序也采用上述格式,Bourne Shell中提供了一条获取和处理命令行选项的语句,即getopts语句。该语句的格式为:

getopts option_string variable

其中option_string中包含一个有效的单字符选项。若getopts命令在命令行中发现了连字符,那么它将用连字符后面的字符同option_string相比较。若有匹配,则把变量variable的值设为该选项。若无匹配,则variable设为?。当getopts发现连字符后面没有字符,会返回一个非零的状态值。Shell程序中可以利用getopts的返回值建立一个循环。

下面代码说明了date命令中怎么使用getopts命令处理各种选项,该程序除了完成unix的标准命令date的功能外,还增加了许多新的选项。

#新date程序

if [ $# -lt 1 ]

then

date

else

while getopts mdyDHMSTJjwahr OPTION

do

case $OPTION

in

m)date '+%m';;

d)date '+%d';;

y)date '+%y';;

D)date '+%D';;

H0date '+%H';;

M)date '+%M';;

S)date '+%S';;

T)date '+%T';;

j)date '+%j';;

J)date '+%y%j';;

w)date '+%w';;

a)date '+%a';;

h)date '+%h';;

r)date '+%r';;

?)echo ”无效的选项!$OPTION“;;

esac

done

fi

有时侯选项中还带一个值,getopts命令同样也支持这一功能。这时需要在option_string中选项字母后加一个冒号。当getopts命令发现冒号后,会从命令行该选项后读取该值。若该值存在,那么将被存在一个特殊的变量OPTARG中。如果该值不存在,getopts命令将在OPTARG中存放一个问号,并且在标准错误输出上显示一条消息。

下面的例子,实现拷贝一个文件,并给文件赋一个新的名字。-c选项指定程序拷贝的次数,-v选项要求显示新创建文件的文件名。

#--拷贝程序

COPIES=1

VERBOSE=N

while getopts vc:OPTION

do

case $OPTION

in

c)COPIES=$OPTARG;;

v)VERBOSE=Y;;

?)echo ”无效参数!“

exit 1;;

esac

done

if [ $OPTIND -gt $# ]

then

echo ”No file name specified“

exit 2

fi

shift 'expr $OPTIND - 1'

FILE=$1

COPY=0

while [ $COPIES -gt $COPY ]

do

COPY='expr $COPY + 1'

cp $FILE $ {FILE} $ {COPY}

if [ VERBOSE = Y }

then

echo ${FILE} $ {COPY}

fi

done

规范Shell:

我们知道环境变量PS1是提示符,看下面程序chdir:

if [ ! -d ”$!“ ]

then

echo ”$1 is not a directory“

exit 1

fi

cd $1

PS1=”'pwd'>“

export PS1

我们执行:

$chdir /usr/ice666

结果提示符号变成/usr/ice666>了吗?没有,为什么?

原因在于:chdir在子Shell中执行,变量PS1的修改在当前Shell中也不会起作用,若要chdir完成意想中的功能,必须在当前Shell中执行该命令。最好的方法就是把其改成一个函数并且在.profile文件中定义。但若要把函数放到单个文件中并在当前Shell中执行,则需要使用 . 命令,并将chdir重写成一个函数,把其中的exit改写成return。下面代码是 .ice_ps的内容:

#--提示符

chdir()

{

if [ !-d ”$1“ ]

then

echo ” $1 is not a directory“

return

fi

cd $1

PS1=”'pwd'>“

export PS1;

}

然后我们在.profile文件中加入下面语句

.ice_ps

然后在切换目录的时候,我们用chdir命令,结果是什么呢,自己实验好了!

调试Shell程序

1>调试shell程序

用户刚编写完Shell程序中,不可避免的会有错误,这时我们可以利用Bsh中提供的跟踪选项,该选项会显示刚刚执行的命令及参数。用户可以通过set命令打开-x选项或在启动Shell使用-x选项将Shell设置成跟踪模式。例如有下面代码ice_tx:

if [ $# -eq 0 ]

then

echo ”usage:sumints integer list“

exit 1

fi

sum=0

until [ $# -eq 0 ]

do

sum='expr $sum + $1'

shift

done

echo $sum

我们用跟踪模式运行:

$sh -x ice_tx 2 3 4

结果显示:

+[ 3 -eq 0 ]

+sum=0

+[ 3 -eq 0 ]

+expr 0+2

+sum=2

+shift

+[ 2 -eq 0 ]

+expr 2+3

+sum=5

+shift

+[ 1 -eq 0 ]

+expr 5+4

+sum=9

+[ 0 -eq 0 ]

+echo 9

9

从上面可以看出,跟踪模式下Shell显示执行的每一条命令以及该命令使用的变量替换后的参数值。一些控制字如if、then、until等没显示。

2>命令分组

Shell中若干命令可以组成一个单元一起执行。为了标识一组命令,这些命令必须放到”()“或”{}“中。放在”()“中的命令将在子Shell中运行,而放在”{}“中的命令将在当前Shell中运行。子Shell中运行的命令不影响当前Shell的变量。当前Shell中运行的命令影响当前Shell的变量。

$NUMBER=2

$(A=2;B=2;NUMBER='expr $A+$B';echo $NUMBER)

结果为:4

$echo $NUMBER

结果为:2

如果把上面的()变成{},结果会是怎么样的呢?

3>使用Shell分层管理器shl

UNIX是一个多道程序设计的操作系统,一些UNIX系统利用这一特性提供了Shell层次管理器shl。使用shl用户一次可以打开多个层次的Shell,其中活跃的Shell可以从终端上获得输入。但所有Shell的输出都可在终端上显示,除非显示被禁止。

多个Shell中有一个为shl,当用户在某个Shell中工作时,可以通过使用特殊字符(一般为Ctrl+z)返回shl。为了同其他Shell区别,shl中提示符为”>>>“。当用户工作在Shell层次管理器中时,可以创建、激活和删除Shell,下面是shl中使用的命令。

create name 产生名为name的层次

delete name 删除名为name的层次

block name 禁止名为name的层次的输出

unblock name 恢复名为name的层次的输出

resume name 激活名为name的层次

toggle 激活近来经常使用的层次

name 激活名为name的层次

layers [-l] name 对于表中的每个层次,显示其正在运行的进程的进程号,-l选项要求显示详细信息。

help 显示shl命令的帮助信息

quit 退出shl以及所有被激活的层次

总结

在前面我们主要介绍了sh的变量、基本语法、程序设计等。如果掌握了这些内容,在学习其他UNIX下编程语言的时候,相信有一定的好处,我们说了,在大多数的UNIX中都提供Bourn Shell,而且很少有象sh这样强大的脚本编辑语言了,是系统管理员和程序员的一笔财富,并且不需要额外的软件环境,对文件等处理借助unix命令,实现起来比c实现还要简单。

[/code:1:0fdddfdb40]

bjchenxu 回复于:-07-14 16:07:52太老了吧,而且shell版中早就加为精华了,是否重复???

alphaliu 回复于:2003-07-14 16:57:41不管重复与否,先up

lwm_13 回复于:2004-03-06 21:43:15up

原文转自:www.ltesting.net

篇5:通用菜单生成程序Windows系统

功能还不是很完善,我正在改进中,这个小东东折腾了我好几天。:oops: [code:1:0c9ffa1d10] /***********主程序****************/ /***ccmenu.c-lcurses-omenu*/ #includestdio.h #includecurses.h #includectype.h #defineENTER10 #defineESCAPE27 WINDOW*me

功能还不是很完善,我正在改进中。这个小东东折腾了我好几天。 :oops:

[code:1:0c9ffa1d10]

/***********  主程序 ****************/

/***clearcase/” target=“_blank” >ccmenu.c -lcurses -omenu            */

#include

#include 

#include

#define ENTER 10

#define ESCAPE 27

WINDOW *menubar,*messagebar,*temp,*temp1;

char param[10][10][13];

void init_curses

{

initscr();

start_color();

init_pair(1,COLOR_WHITE,COLOR_BLUE);

init_pair(2,COLOR_BLUE,COLOR_WHITE);

init_pair(3,COLOR_RED,COLOR_WHITE);

init_pair(4,COLOR_WHITE,COLOR_RED);

curs_set(0);

noecho();

keypad(stdscr,TRUE);

}

void GetSubStr(char *des, char *src, char ch,int n)

{

int i,len;

char *p1,*p, tmp[300];

strcpy( tmp, src );

*des=0;

p1 = tmp;

i=0;

while(i

{

i++;

p = (char *)strchr(p1,ch);

if(p != NULL)

{

*p++ = 0;

p1 = p;

}

}

p = (char *)strchr(p1,ch);

if(p != NULL)

{

*p = 0;

strcpy(des,p1);

}

}

int get_param(char *name)

{

FILE *fp;

char ss[201],xm[3],gs[3];

int i,j;

sprintf(ss,“%s.conf”,name);

if((fp=fopen(ss,“r”))==NULL) return(-1);

for(j=0;j<10;j++) for(i=0;i<10;i++) memset(param[j][i],0,13);

while(1)

{

memset(ss,0,201);

fgets(ss,200,fp);

if(feof(fp)) break;

if(ss[0]=='#') continue;

GetSubStr(xm,ss,'|',0);

GetSubStr(gs,ss,'|',1);

j=atoi(xm);

for(i=1;i<=atoi(gs);i++)

{

sprintf(param[j][0],“%s”,gs);

GetSubStr(param[j][i],ss,'|',i+1);

}

}

fclose(fp);

return(0);

}

void draw_menubar(WINDOW *menubar)

{

int i;

wbkgd(menubar,COLOR_PAIR(2));

for(i=0;i

{

wattron(menubar,COLOR_PAIR(3));

mvwprintw(menubar,0,i*14+2,“%1d.”,i+1);

wattroff(menubar,COLOR_PAIR(3));

mvwprintw(menubar,0,i*14+4,“%-12s”,param[0][i+1]);

}

}

WINDOW **draw_menu(int menu)

{

int i,start_col;

WINDOW **items;

items=(WINDOW **)malloc((atoi(param[menu][0])+1)*sizeof(WINDOW *));

start_col=(menu-1)*14+2;

items[0]=newwin(atoi(param[menu][0])+2,14,3,start_col);

wbkgd(items[0],COLOR_PAIR(2));

box(items[0],ACS_VLINE,ACS_HLINE);

for(i=1;i<=atoi(param[menu][0]);i++)

{

items[i]=subwin(items[0],1,12,3+i,start_col+1);

wprintw(items[i],“%s”,param[menu][i]);

}

wbkgd(items[1],COLOR_PAIR(4));

wrefresh(items[0]);

return items;

}

void delete_menu(WINDOW **items,int count)

{

int i;

for(i=0;i

free(items);

}

int scroll_menu(WINDOW **items,int menu)

{

int key,count,selected=0;

count=atoi(param[menu][0]);

while (1)

{

key=getch();

if (key==KEY_DOWN || key==KEY_UP)

{

wbkgd(items[selected+1],COLOR_PAIR(2));

wnoutrefresh(items[selected+1]);

if (key==KEY_DOWN)

selected=(selected+1) % count;

else

selected=(selected+count-1) % count;

wbkgd(items[selected+1],COLOR_PAIR(4));

wnoutrefresh(items[selected+1]);

doupdate();

}

else if (key==KEY_LEFT || key==KEY_RIGHT)

{

delete_menu(items,count+1);

touchwin(stdscr);

refresh();

if (key==KEY_LEFT)

{

menu-=1;

if(menu<=0) menu=atoi(param[0][0]);

items=draw_menu(menu);

return scroll_menu(items,menu);

}

if (key==KEY_RIGHT)

{

menu+=1;

if(menu>atoi(param[0][0])) menu=1;

items=draw_menu(menu);

return scroll_menu(items,menu);

}

}

else if (key==ESCAPE || key=='0' || key=='q')

{

delete_menu(items,count+1);

return -1;

}

else if (key==ENTER)

{

delete_menu(items,count+1);

return selected;

}

}

}

message(char *ss)

{

wbkgd(messagebar,COLOR_PAIR(2));

wattron(messagebar,COLOR_PAIR(3));

mvwprintw(messagebar,0,0,“%80s”,“ ”);

mvwprintw(messagebar,0,(80-strlen(ss))/2-1,“%s”,ss);

wattroff(messagebar,COLOR_PAIR(3));

wrefresh(messagebar);

}

int main(int argc,char **argv)

{

int key;

int selected_item;

char ss[81];

WINDOW **menu_items;

if(get_param(argv[0]))

{

printf(“n打开配置文件 %s.conf 错!n”,argv[0]);

return(-1);

}

init_curses();

bkgd(COLOR_PAIR(1));

menubar=subwin(stdscr,1,80,1,0);

messagebar=subwin(stdscr,1,80,24,0);

temp=subwin(stdscr,22,80,2,0);

temp1=subwin(stdscr,20,78,3,1);

strcpy(ss,“通用菜单生成程序”);

mvwprintw(stdscr,0,(80-strlen(ss))/2-1,“%s”,ss);

draw_menubar(menubar);

message(“请按数字键选择相应菜单. ESC 或'0'键退出.”);

box(temp,ACS_VLINE,ACS_HLINE);

refresh();

do {

key=getch();

if(isdigit(key)&&key>'0'&&key<=atoi(param[0][0])+'0')

{

werase(messagebar);

wrefresh(messagebar);

menu_items=draw_menu(key-'0');

selected_item=scroll_menu(menu_items,key-'0');

touchwin(stdscr);

refresh();

}

} while (key!=ESCAPE && key!='q' && key!='0');

delwin(temp1);

delwin(temp);

delwin(menubar);

delwin(messagebar);

endwin();

return(0);

}

[/code:1:0c9ffa1d10]

htldm 回复于:2003-10-11 08:54:55菜单参数配置文件 menu.conf

[code:1:26d743f75f]

#

#   格式为: 菜单号|项目个数|项目名称......

#           菜单数量最大为10个

#

0|6|菜单一|菜单二|菜单三|菜单四|菜单五|菜单六|

1|3|menu11|menu12|menu13|

2|8|menu21|menu22|menu23|menu24|menu25|menu26|menu27|menu28|

3|5|menu31|menu32|menu33|menu34|menu35|

4|4|menu41|menu42|menu43|menu44|

5|2|menu51|menu52|

6|1|menu61|

[/code:1:26d743f75f]

海德 回复于:2003-10-11 09:31:47:lol:

kofd 回复于:2003-10-11 09:48:35好东西,珍藏!

foolboy007 回复于:2003-10-11 10:01:07跟俺这的程序差不多

只不过 俺这的菜单配置程序是xml格式的

不知道有啥区别

tingya 回复于:2003-10-11 10:33:24比起我的功能差远了,

可以支持任意多层次的菜单,需要者请到

asp.6to23.com/vcprogram/resdown/resource/fmenu.zip下在,这是图书Linux下的Curses库开发指南>配套原程序.下在后请奖程序中所有的 f_winlabel.h该成f_menuhead.h进行便宜.

sdccf 回复于:2003-10-11 14:34:00错别字多多!

tingya 回复于:2003-10-12 12:25:55能看懂就行,你老兄一定是看懂了。:)

alanlql 回复于:2003-10-12 22:57:38楼上的朋友,我这好象不能下哦,hehe

li 回复于:2003-10-13 09:15:56确实下不了,下不了的东东就不要说了,浪费大家时间~~

kunrong 回复于:2003-10-13 09:34:55确实不错!谢谢楼主!我要好好的读一下!认真的学习一下!

阿徐 回复于:2003-10-13 11:56:11嗬嗬,很有用,但是还有一个问题,比方说,如果我要进入菜单后按enter,如何执行程序,或弹出另外一个子窗口,该如何实现,我也来修改

学习看看,把这个东东完善!!

tingya 回复于:2003-10-13 12:33:25asp.6to23.com/vcprogram/resdown/resource/fmenu.zip

阿徐 回复于:2003-10-13 13:03:35楼上的,还是不能呀,你这个东东阿保存为0字节,不能下

mrhxn 回复于:2003-10-13 13:59:06的确不行!贴一个上来!

kunrong 回复于:2003-10-13 15:28:43真的不能下哦。。。。。期待中。。。。。。

sdccf 回复于:2003-10-13 20:55:18unix-cd.com/softdown/show.asp?id=539

edit 回复于:2003-10-14 09:46:49有错

cc -g f_loadfield.c f_loadlabel.c f_otherfun.c xmlparse.c hashtable.c xmltok.c xmlrole.c f_drawform.c -lform -lcurses

f_loadfield.c:

“./f_menuhead.h”, line 137: error: identifier redeclared: F_MENU

f_loadlabel.c:

sdccf 回复于:2003-10-14 09:53:18请作者说一下在SCOUNIX下的编译方法.

htldm 回复于:2003-10-14 09:56:17这个程序确实还不是很完善,我也只是抛砖引玉,希望大家共同完善它

sdccf 回复于:2003-10-14 09:58:18我是说那个随书的源程序。

lzlcd 回复于:-05-12 09:45:09是个实用的好东东,我试用用看

lhk 回复于:-04-16 22:38:41[quote:4f1885edf3=“htldm”][/quote:4f1885edf3]

message()

不好用,不好用啊。反正我怎么试也没有看见帮助信息?

不知道怎么回事啊!

是一个问题,

怎么弄啊,告诉我啊

zhyesno 回复于:2005-04-18 08:58:20不错,编译了,挺漂亮的.

Thx。。。

myqueue 回复于:2005-04-26 15:34:32myqueue.net.dhis.org/mytui/index.php

也欢迎提宝贵意见

nirvana1125 回复于:2005-04-27 11:21:27编译完成。确实很漂亮。我正在想怎么能实用呢。多谢。多谢!

nirvana1125 回复于:2005-04-27 14:20:20希望大侠们能指明如何调用外部shell,或者4gl等可执行程序。

感激。

原文转自:www.ltesting.net

篇6:javascript模拟Windows系统下的扫雷游戏

很久以前写的 当时都没写注释的 刚加上了 ( ,好多自己都不认识了 ... )

不足的敌方就是本来想写个游戏排名的统计的,等有空了再加上(好像每次都这么说 然后就等好久好久...)

还有就是没有实现:点击第一个格子不能是雷的功能

刚才在手机端 打开了下这篇文章 排版完全乱了...

计时: 0ie6+ ff oprea 谷歌opera 早期版本 默认不支持document.oncontextmenu事件 没有找到好的替代方法

篇7:Sco Unix下用dbxtra调试C程序Windows系统

Sco Unix 下用dbxtra调试C程序 人民银行合肥中心支行陆秉炜 在sco unix 下编程大多离不开C语言,即使是 数据库 应用也有很多是与c搭配使用的,例如 informixe sql /c就可以在c语言中嵌入sql语句,很多人认为在unix下写程序是件很痛苦的事情, 其中一个很重要

ScoUnix下用dbxtra调试C程序

人民银行合肥中心支行 陆秉炜

在scounix下编程大多离不开C语言,即使是数据库应用也有很多是与c搭配使用的,例如

informix esql/c 就可以在c语言中嵌入sql 语句。很多人认为在unix下写程序是件很痛苦的事情,

其中一个很重要原因是不知道在unix下怎样调试程序。其实在sco unix源码调试器是dbxtra或

dbXtra,linux下是gdb。它们类似turbo c的调试器,可以跟踪源码变量。在unix 下调试程序有

如下传统方法:

一、在要调试语句之前,输出要调试的变量,利用printf函数。

二、写日志文件,把结果输出到文件中避免屏幕混乱,利用fprintf()函数。

三、利用sco 内置调试器dbxtra或dbXtra。

dbxtra 适用字符界面,在sco unix的图形界面用dbXtra。(编按:请注意大小写)

以下是dbxtra基本命令:

c               cont      在断点后继续执行

d               delete    删除所设断点

h               help      帮助

e               edit      编辑源程序

n               next      源程序区的内容向下翻一屏。

p               print     显示变量

q               quit      退出dbxtra

r               run       运行程序,直到遇上设置的断点

rr              rerun     再次运行

s               step      单步运行

st              stop      设置断点

j               status    显示当前断点

t        where  显示当前状态,列出所有设置的变量值

di              display   开显示窗,用于查看变量

ud              undisplay 删除显示窗的条目

f               forward   源程序区的内容向上 翻一屏。

B               backward  源程序区的内容向下 翻一屏。

Stopi           stop inst 设置断点

tracei          trace inst跟踪子程序

dbxtra [options] [objectfile ]

dbxtra         在启动时有个参数-Idir值得一提.我们在编写一个较大程序的时候,通常源程序和编译生成

的可执行文件都放在不同的目录中,这样便于管理,

默认dbxtra将在可执行文件所在的目录下找匹配c的源程序。

当我们启动时,指定-I参数,dbxtra就会到我们指定的目录下找匹配的c程序。         例如:

dbxtra -I“workc” program1

源程序在用clearcase/“ target=”_blank“ >cc编译时要带上-g 参数,这样是加上符号表等调试信息。只有这样编译过的文件,dbxtra才可以调试。调试信息使源代码和机器码关联。

下面这个C程序输出结果和我们的预想结果不一样,说明某些地方有错误。我们用调试器来

调试它:

程序一:

t.c

main()

{  int   i=10 ,*p1;

float j=1.5,*p2;

p1=&

p2=&

p2=p1;

printf(”%d,%dn“,*p1,*p2);

}

首先带上-g参数编译  cc -g -o t t.c

启动调试器          dbxtra t

屏幕显示:

1.main()

2.{  int   i=10 ,*p1;

3.   float j=1.5,*p2;

4.   p1=&

5.   p2=&

6.   p2=p1;

7.   printf(”%d,%dn“,*p1,*p2);

8.}

C[browse] File:t.c    Func.-

Readubg symbolic information

Type    'help' for help

(dbxtra)

(dbxtra)

设置断点:

(dbxtra)stop at 5

运行:

(dbxtra) run

程序自动在第5行停下。

这时我们可以看变量的值。

(dbxtra) print *p1

单步执行。

(dbxtra)  step

程序将执行第5行源码,指针将移到第6行。

(dbxtra)  print *p2

(dbxtra) step

程序执行了第6行源码后,将指针移到第7行。

(dbxtra) print *p1 , *p2

我们发现         在执行了第6行源码后,*p1,*p2的值就不对了,所以问题就出在第6行上。仔细检查后发现指针

p1指向整型,指针p2指向实型。它们之间的赋值要进行强制类型转换。这种错误在C程序中是很常见的。

有时我们在调试一些程序时,要在整个程序运行中时刻监视莫些变量的值,例如程序一中我们

要时刻了解*p1,*p2的值,除了在每一行程序执行完后,打print *p1,*p2外,还可以开一个显示窗口。

(dbxtra)display *p1,*p2

用undisplay 删掉不想要的变量。

有些程序运行时要带参数,mycat /etc/passwd 在调试时候

(dbxtra) run '/etc/passwd'

再运行时,无需再写一遍参数。

(dbxtra) rerun

在涉及到curses库编程或屏幕有大量的人机界面时,为了调试方便,我们可以把程序输出结果

重定向到个虚屏。

(dbxtra) run >/dev/tty03

当然要先把tty03 disable 掉。(disable tty03)

dbxtra还有很多高级的用法,有兴趣的读者可以参照dbxtra本身的help,进一步研究。

kelvin 回复于:-06-17 18:10:20多文件make出来的怎么调试,程序包含esql。

原文转自:www.ltesting.net

篇8:一个SCO UNIX下端口扫描的C程序Windows系统

/*****************************************/ /*W.X.Y.2001-3编译成功*/ /*运行于SCO UNIX 系统*/ /*****************************************/ #includestdio.h #includesys/types.h #includesys/socket.h #includenetinet/in.h #includeerrno.h #include

/*****************************************/

/* W.X.Y.2001-3 编译成功                 */

/* 运行于SCOUNIX系统                   */

/*****************************************/

#include 

#include 

#include 

#include 

#include 

#include 

#include 

int main(int argc, char **argv)

{

int probeport = 0;

struct hostent *host;

int err, i, net;

int startport,endport;

struct sockaddr_in sa;

startport=1;

endport=700;

if(argc==3)

{

startport=endport=atoi(argv[2]);

}

if(argc==4)

{

startport=atoi(argv[2]);

endport=atoi(argv[3]);

}

for(i=startport;i

{

strncpy((char *)&sa,”“,sizeof sa);

sa.sin_family = AF_INET;

if(isdigit(*argv[1]))

sa.sin_addr.s_addr = inet_addr(argv [1]);

else if((host = gethostbyname(argv[1])) != 0)

strncpy((char *)&sa.sin_addr, (char *)host->h_addr,sizeof sa.sin_addr);

else

{

/*pherror(argv [1]); */

printf(”Usage: portscan address|hostname [start_port end_port]n“);

printf(” default port number from %d to %dn“,startport,endport);

exit (2);

}

sa.sin_port = htons(i);

net = socket(AF_INET,SOCK_STREAM,0);

if(net<0)

{

perror(”nsocket“);

exit(2);

}

err = connect(net,(struct sockaddr *) &sa,sizeof sa);

if(err<0)

{

/*

printf(”%s %-5d %sr“,argv[1],i,strerror(errno));

*/

printf(”r“);

fflush(stdout);

if(argc==3)

printf(”%s %-5d refused. n“,argv[1],i);

}

else

{

printf(”%s %-5d aclearcase/“ target=”_blank“ >ccepted. n”,argv[1],i);

if(shutdown(net,2)<0)

{

perror(“nshutdown”);

exit(2);

}

}

close(net);

}

printf(“r”);

fflush(stdout);

return(0);

}

/*程序结束*/

/*编译方法:*/

/* $cc -o portscan portscan.c -lnsl -lsocket*/

jysww 回复于:2003-02-19 22:43:15up!

yujf 回复于:2003-08-29 10:58:19怎么没有注释呀?可以提供点吗?

原文转自:www.ltesting.net

【SCO Unix下开发游戏程序Windows系统】相关文章:

1.Unix系列shell程序编写(中)Windows系统

2.JAVA程序开发简历

3.UNIX系统安全Windows系统

4.Windows系统下安装Python的SSH模块教程

5.SGI产品介绍Windows系统

6.Windows文件大揭密Windows系统

7.《WIN下简单关闭TCP/UDP端口方法》Windows系统

8.游戏开发简历表格

9.电子商务系统的开发计划书

10.巧妙节约Win98系统资源Windows系统

下载word文档
《SCO Unix下开发游戏程序Windows系统.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度: 评级1星 评级2星 评级3星 评级4星 评级5星
点击下载文档

文档为doc格式

  • 返回顶部