Linux下more命令C语言实现实践 (Unix-Linux编程实践教程)

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;
    //白底黑字 33[7m str 33[m
    printf("33[7m more? 33[m");
    while( (c = getchar()) != EOF)
    {
        if ( c == 'q')
            return 0;
        else if ( c == ' ')
            return PAGELEN; //空格返回PAGELEN行
        else if ( c == '
' )  
            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("33[7m more? 33[m");  
    while( (c = getc(cmd)) != EOF ) //此处的getchar()从stdin读取数据,getc(cmd)从文件cmd(/dev/tty)中读入数据  
    {  
        if(c == 'q')  
          return 0;  
        if(c == ' ')  
          return PAGELEN;  
        if(c == '
')  
          return 1;  
    }  
    return 0;  
}  
原文地址:https://www.cnblogs.com/loveyouyou616/p/7773026.html