Linux 编程实践(一)more 的实现

来源:互联网 发布:程序员未来的发展方向 编辑:程序博客网 时间:2024/05/21 17:00

参考电子书《Unix&Linux编程实践》P28 1.6动手实践
下面是more的第一个版本:

#include <stdio.h>#include <stdlib.h>#define PAGELEN 24#define LINELEN 512void 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 512void 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
原创粉丝点击