2009-10-24
第一章中的more01.c程序在CentOS 5.3下应该加入头文件stdlib.h,否则在编译exit时会报错。编译过程按照书中所写即可,但在使用时书中书写如下:
more01 more01.c
实际应该如下:
./more01 more01.c (注意:此时在生成more01的文件夹目录中,本章中后面的命令中也存在同样的问题。)
对于more01而言,是从标准输入读数据的,而在命令ls /bin | ./more01中标准输入定向了ls,所以输出出现了错误。
所以在more02中对于相关部分进行了修改(注意头文件部分同more01),该程序解决了ls问题,但是未解决“ more?” 上滚以及在使用空格和q控制是需要使用回车加以确认的问题。
对于解决按键问题,网上查到有2种方式,一种是用curses库中的getch函数,另一种使用termio.h头文件修改终端的属性来达到。
现在只解决了使用termio.h的问题,对于curses该如何修改尚不清楚,以下是使用termio.h解决的程序如下
/* more03.c - version 0.3 of more
* read and print 24 lines then pause for a few special commands
* feature of version 0.3: reads from /dev/tty for commands
*/
#include
#include
//#include
#include
#define PAGELEN 24
#define LINELEN 512
static struct termios now_attr,tem_attr;
void do_more(FILE *);
int see_more(FILE *);
void keyboard(int how)
{
if(how == 0)
{
tcgetattr(0,&now_attr);
tem_attr = now_attr;
tem_attr.c_lflag &= ~ICANON;
tem_attr.c_lflag &= ~ECHO;
tem_attr.c_cc[VMIN] = 1;
tem_attr.c_cc[VTIME] = 0;
tcsetattr(0,TCSANOW,&tem_attr);
}
else
tcsetattr(0,TCSANOW,&now_attr);
}
int main( int ac , char *av[] )
{
FILE *fp;
// initscr();
if ( ac == 1 )
do_more( stdin );
else
keyboard(0);
while ( --ac )
if ( (fp = fopen( *++av , "r" )) != NULL )
{
do_more( fp ) ;
fclose( fp );
}
else
{
keyboard(1);
exit(1);
}
// endwin();
return 0;
}
void do_more( FILE *fp )
/*
* read PAGELEN lines, then call see_more() for further instructions
*/
{
char line[LINELEN];
int num_of_lines = 0;
int see_more(FILE *), reply;
FILE *fp_tty;
fp_tty = fopen( "/dev/tty", "r" ); /* NEW: cmd stream */
if ( fp_tty == NULL ) /* if open fails */
{
keyboard(1);
exit(1); /* no use in running */
}
while ( fgets( line, LINELEN, fp ) ){ /* more input */
if ( num_of_lines == PAGELEN ) { /* full screen? */
reply = see_more(fp_tty); /* NEW: pass FILE * */
// reply = see_more();
if ( reply == 0 ) /* n: done */
{
keyboard(1);
break;
}
num_of_lines -= reply; /* reset count */
}
if ( fputs( line, stdout ) == EOF ) /* show line */
{
keyboard(1);
exit(1); /* or die */
}
num_of_lines++; /* count it */
}
}
int see_more(FILE *cmd) /* NEW: accepts arg */
//int see_more()
/*
* print message, wait for response, return # of lines to advance
* q means no, space means yes, CR means one line
*/
{
int c;
printf("\033[7m more? \033[m"); /* reverse on a vt100 */
while( (c=getc(cmd)) != EOF ) /* NEW: reads from tty */
{
if ( c == 'q' ) /* q -> N */
return 0;
if ( c == ' ' ) /* ' ' => next page */
return PAGELEN; /* how many to show */
if ( c == '\n' ) /* Enter key => 1 line */
return 1;
}
return 0;
}