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

参考电子书《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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值