unix/linux more命令的实现

来源:互联网 发布:金融学中的优化方法 编辑:程序博客网 时间:2024/05/21 09:14

Understanding Unix/Linux Programming(Unix/Linux编程实践教程)

学习模式:

(1)它能做什么?

(2)它是如何实现的?

(3)能不能自己编写一个?

(实验环境:gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4) 


/* more01.c  - version 0.1 of more *read and print 24 lines then pause for a few special commands */#include<stdio.h>#definePAGELEN24#defineLINELEN512void do_more(FILE *);int  see_more();int main( int ac , char *av[] ){FILE*fp;if ( ac == 1 )do_more( stdin );elsewhile ( --ac )if ( (fp = fopen( *++av , "r" )) != NULL ){do_more( fp ) ; fclose( fp );}elseexit(1);return 0;}void do_more( FILE *fp )/* *  read PAGELEN lines, then call see_more() for further instructions */{charline[LINELEN];intnum_of_lines = 0;intsee_more(), reply;while ( fgets( line, LINELEN, fp ) ){/* more input*/if ( num_of_lines == PAGELEN ) {/* full screen?*/reply = see_more();/* y: ask user  */if ( reply == 0 )/*    n: done   */break;num_of_lines -= reply;/* reset count*/}if ( fputs( line, stdout )  == EOF )/* show line*/exit(1);/* or die*/num_of_lines++;/* count it*/}}int see_more()/* *print message, wait for response, return # of lines to advance *q means no, space means yes, CR means one line */{intc;printf("\033[7m more? \033[m");/* reverse on a vt100*/while( (c=getchar()) != EOF )/* get response*/{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;}




相比上面的程序,下面这个程序多了几个扩展功能。

(1)当程序按空格或者输入“q”后,不需要按回车键直接处理。

(2)打印文件中已经显示的百分比。

相比课本,未完成功能如下,在网上找不到合适的资料,待续。

(1)确定终端打印的行数列数(终端类)

//more command#include<stdio.h>#include<stdlib.h>#define PAGELEN 24#define LINELEN 512void do_more(FILE* );int see_more(FILE*,int );int sum_size  = 0;int main(int ac,char *av[]){FILE* fp;if(ac == 1)do_more(stdin);elsewhile(--ac){if((fp = fopen(*++av,"r")) != NULL){fseek(fp,0L,SEEK_END);  /*利用fseek函数将指针定位在文件结尾的位置*/sum_size=ftell(fp);     /*利用ftell函数返回指针相对于文件开头的位置,以字节计算*/printf("\n the type of file is : %d\n",sum_size);   /*进行输出文件总大小*/fseek(fp,0L,SEEK_SET);   /*将fp设置文件开始的位置*/do_more(fp);fclose(fp);}elseexit(1);}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*,int),reply;FILE* fp_tty;fp_tty = fopen("/dev/tty","r");if(fp_tty == NULL)exit(1);while(fgets(line, LINELEN,fp)){if(num_of_lines == PAGELEN){int cur_size=ftell(fp);   /*利用ftell函数返回指针相对于文件开头的位置,以字节计算*/int per= (int)100* cur_size/sum_size; //计算当前占用比例。reply =see_more(fp_tty,per);if(reply == 0 )break;num_of_lines -= reply;}if(fputs(line,stdout) == EOF)exit(1);num_of_lines++;}}int see_more(FILE* cmd,int per){/*print message, wait for response, return # of lines to advanceq means no, space means yes CRmeans one line*/int c;system("stty -icanon");//关闭缓冲区,输入字符无需回车直接接受printf("\033[7m more?--%d%--\033[m",per);  //实现反白while((c=getc(cmd))!=EOF){if(c == 'q')return 0;if(c == ' ')return PAGELEN;if(c == '\n')return 1;}}



运行结果




0 0
原创粉丝点击