参考电子书《Unix&Linux编程实践》P28 1.6动手实践
下面是more的第一个版本:
#include <stdio.h>
#include <stdlib.h>
#define PAGELEN 24
#define LINELEN 512
void do_more(FILE * );
int see_more();
int main( int ac, char * av[] )
{
FILE *fp;
if (ac==1)
do_more(stdin);
else
while(--ac)
if((fp=fopen(* ++av,"r"))!=NULL)
{
do_more(fp);
fclose(fp);
}
else
exit(1);
return 0;
}
void do_more(FILE *fp)
{
char line[LINELEN];
int num_of_lines=0;
int see_more(),reply;
while(fgets(line,LINELEN,fp)){
if(num_of_lines== PAGELEN){
reply=see_more();
if(reply==0)
break;
num_of_lines-=reply;
}
if(fputs(line,stdout)==EOF)
exit(1);
num_of_lines++;
}
}
int see_more()
{
int c;
printf("\033[7m more?\033[m");
while((c=getchar())!=EOF)
{
if(c=='q')
return 0;
if(c==' ')
return PAGELEN;
if(c=='\n')
return 1;
}
return 0;
}
编译并运行上述代码, 这个程序可以完成基本的功能,显示24行后就停下来等待输入,而且在屏幕下方会有反白的more? 当按回车会显示下一行。
$cc more01.c -o more01
$./more01 more01.c
$ls /bin|./more01
没有在显示24后暂停,等待用户输入。原因书上有描述
More的第二个版本
/dev/tty,是键盘和显示器的设备描述文件,向这个文件写相当于显示在用户的屏幕上,读相当于从键盘获取用户的输入。
more 有两个输入,程序的标准输入是ls的输出,将其分页显示到屏幕上,当more需要用户输入时,它可以从/dev/tty得到数据。
运用上述知识改进more01.c 得到more02.c
#include <stdio.h>
#include <stdlib.h>
#define PAGELEN 24
#define LINELEN 512
void do_more(FILE * );
int see_more();
int main( int ac, char * av[] )
{
FILE *fp;
if (ac==1)
do_more(stdin);
else
while(--ac)
if((fp=fopen(* ++av,"r"))!=NULL)
{
do_more(fp);
fclose(fp);
}
else
exit(1);
return 0;
}
void do_more(FILE *fp)
{
char line[LINELEN];
int num_of_lines=0;
int see_more(),reply;
FILE *fp_tty;
fp_tty=fopen("/dev/tty","r"); /*NEW:cmd stream*/
if(fp_tty==NULL)
exit(1);
while(fgets(line,LINELEN,fp)){
if(num_of_lines== PAGELEN){
reply=see_more(fp_tty); /*NEW:pass FILE * */
if(reply==0)
break;
num_of_lines-=reply;
}
if(fputs(line,stdout)==EOF)
exit(1);
num_of_lines++;
}
}
int see_more(FILE *cmd) /*NEW: accepts arg*/
{
int c;
printf("\033[7m more?\033[m");
while((c=getc(cmd))!=EOF)
{
if(c=='q')
return 0;
if(c==' ')
return PAGELEN;
if(c=='\n')
return 1;
}
return 0;
}
编译并运行上述代码
$cc more02.c -o more02
$ls /bin|./more02