1. more第一版
实现基础功能,显示每一页固定24行文本,“q Enter”退出, “Enter” 下一行, “space Enter”下一页。
#include<stdio.h> #include<stdlib.h> #define PAGELEN 5 #define LINELEN 512 //实现基础功能,显示每一页固定24行文本,“q Enter”退出, “Enter” 下一行, “space Enter”下一页。 void do_more(FILE *); int see_more(); int main (int ac, char *av[]) { FILE *fp; if ( ac == 1) do_more(stdin); //如果没有第2个参数 从标准输入获取内容 else { while(--ac){ //* ++av 命令行第二个参数(文件名) 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){ //最多显示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; //白底黑字 \033[7m str \033[m printf("\033[7m more? \033[m"); while( (c = getchar()) != EOF) { if ( c == 'q') return 0; else if ( c == ' ') return PAGELEN; //空格返回PAGELEN行 else if ( c == '\n' ) return 1; //回车 只返回一行 } return 0; }
2.more第二版
解决上一个版本“ls -l /etc | ./more01”, “ls -l /etc” 输出重定向为“./more01” 输入时 由于see_more() 函数中getchar()与do_more(FILE *fp)中读取都是stdin中的数据,时输出一页后不回暂停等待命令。解决方法是: see_more()改为通过/dev/tty(键盘与显示设备的描述文件),读取键。
#include <stdio.h> #include <stdlib.h> #define PAGELEN 5 #define LINELEN 512 void do_more(FILE *); int see_more(FILE *); int main (int ac, char *av[]) { FILE *fp; if (ac == 1) do_more(stdin); else { while(--ac) { if ((fp = fopen(av[1],"r")) != NULL ) { do_more(fp); fclose(fp); } else { exit(1); } } } return 0; } void do_more(FILE *fp) { char line[LINELEN]; int reply; int number_line = 0; FILE *fp_tty; fp_tty = fopen("/dev/tty","r"); // 打开/dev/tty设备文件 键盘与显示设备的描述文件),读取键 if(fp_tty == NULL) exit(1); while(fgets(line, LINELEN, fp) != NULL) { if(number_line == PAGELEN) { reply = see_more(fp_tty); if(reply == 0) break; number_line -= reply; } if( fputs(line, stdout) == EOF) exit(1); number_line ++; } } int see_more(FILE *cmd) { int c; printf("\033[7m more? \033[m"); while( (c = getc(cmd)) != EOF ) //此处的getchar()从stdin读取数据,getc(cmd)从文件cmd(/dev/tty)中读入数据 { if(c == 'q') return 0; if(c == ' ') return PAGELEN; if(c == '\n') return 1; } return 0; }