Linux系统编程21-简单的more命令实现

/dev/tty: 键盘和显示器设备描述文件

  • 向该文件写->显示在用户屏幕
  • 向该文件读->从键盘获取用户输入

当more需要用户输入可以从/dev/tty得到数据

#include <stdio.h>
#include <stdlib.h>

#define PAGELEN 24
#define LINELEN 512

void do_more(FILE*);
int see_more(FILE*);

/*
    main 函数根据命令行参数打开并读取文件,
    如果没有命令行参数则从标准输入读取。
    调用 do_more 函数来执行分页显示的操作。
*/
int main(int argc, char const *argv[])
{
    FILE* fp;
    if(argc == 1)
        do_more(stdin); // 没有参数时读取标准输入
    else
        while(--argc){
            // 逐个打开文件并读取
            if((fp = fopen(*++argv, "r")) != NULL){ 
                do_more(fp);
                fclose(fp);
            }else
                exit(1);
        }

    return 0;
}

/*
do_more 函数对于每个文件,从文件中读取内容并分页显示,
等待用户按下空格或回车以继续显示,或者按下 q 退出显示。
*/
void do_more(FILE* fp){
    char line[LINELEN];
    int num_of_lines = 0;   //已经显示的行数
    int see_more(FILE*), reply;
    FILE* fp_tty;   //指向 /dev/tty 设备文件的文件指针
    //该设备文件指向当前正在使用的终端设备,用来接收用户的输入。
    fp_tty = fopen("/dev/tty","r"); 

    if(fp_tty == NULL){
        exit(1);
    }

    while(fgets(line, LINELEN, fp)){
        //当显示行数达到 PAGELEN 定义的行数时就停止并调用 see_more 函数等待用户输入
        if(num_of_lines == PAGELEN){
            reply = see_more(fp_tty);
            if(reply == 0)
                break;
            //如果读取一页,num_of_lines又变成0了,新的一页开始
			//如果读取一行,则下次循环又满足 num_of_lines == PAGELEN 条件 ,继续输入指令
            num_of_lines -= reply;  //reset count
        }

        if(fputs(line, stdout) == EOF)
            exit(1);
        num_of_lines++;
    }
}

//q-退出,空格翻页,回车显示一行
int see_more(FILE* cmd){
    int c;
	// \033[7m 是设置反显(即黑底白字)的控制码,\033[m 则是关闭反显的控制码
    printf("\033[7m more? \033[m");
    //使用 getc 函数从 fp_tty 文件指针中获取用户的输入。
    while((c=getc(cmd)) != EOF){
        //按下 q 时,退出函数并返回 0,表示不再显示更多内容。
        if(c=='q')
            return 0;
        //按下空格时,返回 PAGELEN 定义的行数,表示继续显示下一页。
        if(c==' ')
            return PAGELEN;
        //按下回车时,返回 1,表示只显示下一行内容。
        if(c=='\n')
            return 1;
    }
    return 0;
}

getc 和 getchar 有什么区别
相同:都是 C 语言中用于从输入流中读取一个字符的函数

不同:

  • getchar 从标准输入流(通常是键盘)中读取一个字符。
    它是 C 标准库中的函数,可以不传递参数,也可以传递参数 stdin,
    表示从标准输入流中读取一个字符。
  • getc 也可以从标准输入流中读取一个字符,但它还可以从其他流中读取一个字符。
    它需要传递一个 FILE 类型的指针参数,表示从哪个流中读取一个字符。
posted @ 2023-06-27 15:12  言叶以上  阅读(36)  评论(0编辑  收藏  举报