下面是小编收集整理的一个SCO UNIX下实现F3行复制功能键的C程序Windows系统,本文共7篇,仅供参考,希望能够帮助到大家。本文原稿由网友“枯树与绿茵”提供。
篇1:一个SCO UNIX下实现F3行复制功能键的C程序Windows系统
/*#Newsh.c源程序清单*/ #includetermio.h #includesignal.h #defineESCAP27/*功能键引导符*/ /*应根据所用设备及工作需要, 修改以下各值, 请参考你的有关手册.*/ /*以下4行为主机键盘功能键的值:*/ #defineCF177/*F1键*/ #defineCF278/*F2键*/ #defineCF379
/*#Newsh.c 源程序清单*/
#include
#include
#define ESCAP 27 /* 功能键引导符*/
/* 应根据所用设备及工作需要,
修改以下各值,
请参考你的有关手册. */
/* 以下4行为主机键盘功能键的值:*/
#define CF1 77 /* F1键 */
#define CF2 78 /* F2键 */
#define CF3 79 /* F3键 */
#define CF4 80 /* F4键 */
/*以下4行为终端键盘功能键的值: */
#define PF1 80 /* PF1键 */
#define PF2 81 /* PF2键 */
#define PF3 82 /* PF3键 */
#define PF4 83 /* PF4键 */
/*以下4行为终端键盘功能键的值: */
#define AF1 32 /* Alt+F1键*/
#define AF2 33 /* Alt+F2键*/
#define AF3 34 /* Alt+F3键*/
#define AF4 35 /* Alt+F4键*/
/*以下4行为终端键盘功能键的值: */
#define TF1 77 /* F1键 */
#define TF2 78 /* F2键 */
#define TF3 79 /* F3键 */
#define TF4 80 /* F4键 */
#define ABORT 68 /* 放弃键 */
#define INSERT 65 /* 插入键 */
#define LENGTH 100 /* 命令行长度 */
#define LF 10 /* 换行符 */
#define BACKSP 8 /* 退格符 */
#define QUIT 4 /*退出键Ctrl+d*/
#define PROMT0 “# ” /* 提示符 */
#define PROMT1 “$ ” /* 提示符 */
#define ERROR “error,bad directory\\n”
#define MESS “\\n\\nEnter terminal flag: ”
char buff[LENGTH*2];
char *str1=buff;
char *str2=buff+LENGTH;
char *ii,*jj,*tmp;
char chr,flag0,flag1,flag2;
char f1,f2,f3,f4;
main(argc,argv)
int argc;
char *argv[];
{ /* main */
struct termio tdes;
char *getenv(char*);
char *ttyname(int);
char *pt;
tmp=ttyname(0);
for( ;*tmp;tmp++);
if (flag1=(*(--tmp)<'A')) {
f1=CF1;
f2=CF2;
f3=CF3;
f4=CF4;
}
else { /* else 0 */
if (argc==1){
write(1,MESS,23);
read(0,&flag2,1);
} else
flag2=*argv[1];
switch (flag2) { /*switch*/
case '0':
f1=TF1;
f2=TF2;
f3=TF3;
f4=TF4;
break;
case '1':
f1=PF1;
f2=PF2;
f3=PF3;
f4=PF4;
break;
case '2':
default:
f1=AF1;
f2=AF2;
f3=AF3;
f4=AF4;
break;
} /*switch*/
} /* else 0 */
if(!(pt=getenv(“PS1”)))
pt=getuid?PROMT1:PROMT0;
do { /* do while 1 */
ioctl(0,TCGETA,&tdes);
tdes.c_lflag &=~ECHO;
tdes.c_lflag &=~ICANON;
tdes.c_clearcase/“ target=”_blank“ >cc[VMIN]=1;
tdes.c_cc[VTIME]=0;
ioctl(0,TCSETA,&tdes);
signal(SIGINT,SIG_IGN);
ii=str2; str2=str1;
str1=ii; jj=str2;
flag0=1;
write(1,pt,2);
do { /* do while2 */
read(0,&chr,1);
switch(chr)
{ /*switch1*/
case ESCAP:
funkey();
break;
case BACKSP:
if (ii>str1) {
ii--;
if (jj>str2)
jj--;
write(1,”\\b \\b“,3);
}
break;
default:
*ii++=chr;
write(1,&chr,1);
if (flag0) jj++;
} /* switch 1 */
} /* do while2 */
while (chr!=LF && chr!=QUIT);
for (--ii;*ii;*ii++=0) ;
tdes.c_lflag |=ECHO;
tdes.c_lflag |=ICANON;
tdes.c_cc[VMIN]=4;
ioctl(0,TCSETA,&tdes);
signal(SIGINT,SIG_DFL);
tmp=str1;
for(;*tmp==' ';tmp++);
if (*tmp++=='c' && *tmp++=='d'
&& (*tmp==' ' || *tmp==0))
{
for(;*tmp==' ';tmp++);
if (!*tmp)
tmp=getenv(”HOME“);
if (chdir(tmp))
write(1,ERROR,20);
continue;
}
system(str1); /*执行用户命令*/
} while(chr!=QUIT); /*dowhlie1*/
} /* main */
funkey()
{ /* funkey */
read(0,&chr,1);
if (flag1 || (flag2=='1'))
read(0,&chr,1);
if (chr==f1) {
if (*jj) {
write(1,jj,1);
*ii++=*jj++;
}
return(0);
}
if (chr==f2) {
if(finchr())
do {
write(1,jj,1);
*ii++=*jj++;
}
while(jj
return(0);
}
if (chr==f3) {
while ( *jj ) {
write(1,jj,1);
*ii++=*jj++;
}
return(0);
}
if (chr==f4) {
if(finchr()) jj=tmp;
return(0);
}
if (!flag1 && !(flag2=='1'))
read(0,&chr,1);
if (chr==ABORT) {
ii=str1; jj=str2;
write(1,”\\\\\\n “,4);
return(0);
}
if (chr==INSERT)
flag0 ^= 1;
return(0);
} /* funkey */
finchr()
{
read(0,&chr,1);
tmp=jj;
do tmp++;
while (*tmp && *tmp!=chr);
return(*tmp);
}
/*#end*/
【发表回复】【查看CU论坛原帖】【添加到收藏夹】【关闭】jxp 回复于:-01-13 10:01:12法王,这个程序什么意思,能否讲清楚点
原文转自:www.ltesting.net
篇2:一个SCO UNIX下端口扫描的C程序Windows系统
/*****************************************/ /*W.X.Y.-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 %d\\n“,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 %s\\r“,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 回复于:-02-19 22:43:15up!
yujf 回复于:2003-08-29 10:58:19怎么没有注释呀?可以提供点吗?
原文转自:www.ltesting.net
篇3: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“\\work\\c” 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,%d\\n“,*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,%d\\n“,*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
篇4:python在windows下实现备份程序实例
最近更 新
python 获取本机ip地址的两个方法
Python 异常处理实例详解
wxpython学习笔记(推荐查看)
Python isinstance判断对象类型
动态创建类实例代码
使用python实现拉钩网上的FizzBuzzWhizz问
Python SQLite3数据库操作类分享
Python 面向对象 成员的访问约束
Python模块学习datetime介绍
Python random模块(获取随机数)常用方法
热 点 排 行
Python入门教程 超详细1小时学会
python 中文乱码问题深入分析
比较详细Python正则表达式操作指
Python字符串的encode与decode研
Python open读写文件实现脚本
Python enumerate遍历数组示例应
Python 深入理解yield
Python+Django在windows下的开发
python 文件和路径操作函数小结
python 字符串split的用法分享
篇5: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 20\\n“);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
篇6: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 “$I\\c”
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 回复于:-03-06 21:43:15up
原文转自:www.ltesting.net
篇7:windows下实现查看进程对应程序的方法
这篇文章主要为大家介绍了windows下实现查看进程对应程序的方法,对于进行电脑病毒查杀的时候非常实用,需要的朋友可以参考下
本文简单介绍了windows下实现查看进程对应程序的方法,对于一些木马的查杀非常有用!
很多时候我们整天忙着杀毒,然后在任务管理器寻找该死的木马进程?但是找到之后却苦于不知道哪个进程对应什么程序?
没关系,这时候可以试试用系统自带的功能来查看进程(此处以Windows XP为例)
1.首先,点击“开始”菜单,进入到 “运行”
2.然后我们在 “运行”里面输入“wmic”并回车 (注意:第一次使用会出现“正在安装WMIC”的字样,一会就可以进入了,
windows下实现查看进程对应程序的方法
,
3.然后就来到一个类似CMD命令执行符的界面。
4.之后我们在命令行里面输入“Process”(就是进程的意思)然后回车
5.这时候我们就会看到进程出现了 ,后面对应的就是该进程所对应的程序位置。
至此,找到进程对应程序的位置之后,结束进程再删除病毒文件即可!
此外还要记得搜索注册表里面的启动项以及windows开机启动项,删除或结束相关的病毒启动项,以保证彻底杀毒!