zoukankan      html  css  js  c++  java
  • linux文件管理小结之自己定义more

    1.more命令功能

    more命令用于查看内容超过一屏的文本(相似于cat)
    基本功能
    1.输入backspace :内容翻一屏
    2.输入enter : 内容翻一行
    3.输入q:退出
    4.实时显示已读文件比例

    2.实现思路

    1. 从命令中获取须要操作的文件
    2. 打开文件:open(filename,O_RDONLY);
    3. 获取文件总行数:
      lseek(fd,0,SEEK_END);//移动文件指针至文件末
      page_sum = lseek(fd,0,SEEK_CUR);//计算与文件头偏移量。就可以得到文件总行数
    4. 命令初始读取内容(定义整屏为10行)
      设置一标志量 存储 每次须要显示的行数,如果n。则运行n次下操作
      用read(fd,str,1); 每次读取一个字节,读到’ ’停止
      而且在每次读完之后须要用lseek(fd,0,SEEK_CUR)来获取当前已显示行数。用于得到文件已阅比例
    5. 每次操作完毕后接受用户指令
      see_more();
      函数接受用户输入,依据输入值返回要翻的页数
    6. close(fd);

    过程收获

    1. 反显文字:
      做这个时才了解到linux 上 printf的功能好丰富,清屏。移动光标,一应俱全。
    2. 保证more的提示信息总显示在终端的最下端。并不反复显示
      刚開始准备使用,printf(“33[s”)记录光标位置。输出后,再用printf(“33[u33[K”);光标归位并清行;
      然而在输出提示信息中。还须要接受用户的输入,会产生换行符,而换行之后,光标归位会失效,记录于此。
      终于是用printf(“33[1A33[K”)将光标上移一行,并清空该行内容,用以覆盖提示信息
    3. 文件比例的实现
      这个的实现细节上文已经提到,之所以再做赘述,是由于笔者在实现过程中由于此功能卡顿非常久
      由于须要按行读的缘故,想要使用fgets()来读取文本。可是打开文件又用的是系统函数open(),而非fopen(),于是就产生了混用的情况。
      而结果是每次用lseek()读取当前文件指针偏移量时,得到的值都是文件首与文件尾的偏移量,改为fseek()后,值变为0,探究无果,不知其因,记录于此,日后再谈

    代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <fcntl.h>
    
    #define PAGENUM 10 //定义一屏为10行
    
    void do_more(int fd);
    int see_more(  int sum, int now);
    
    int main( int argc, char **argv )
    {
        int fd;
        if( argc == 1 )//參数不合法则返回
        {
            return 0;
        }
        else
        {
            while( argc-->1 )
            {
                if( (fd = open(*++argv,O_RDONLY)) != -1 )
                {   
                    do_more(fd);
                    close(fd);
                }
                else
                {
                    printf("Error: can't open file
    ");
                    exit(1);
                }
            }
        }
        return 0;
    }
    
    void do_more(int fd)
    {
        char str[3];
        int page_num = 0;//保存每次须要跳转的行数
        int rel;
        int page_now = 0;//保存当前行数(初始为0)
        int page_sum;//保存总行数
    
    
        lseek(fd,0,SEEK_END);//移动文件指针至文件末
        page_sum = lseek(fd,0,SEEK_CUR);//计算与文件头偏移量,即文件总行数
        lseek(fd,0,SEEK_SET);//移动文件指针至文件头
    
        while( page_now<page_sum )
        {
            while(read(fd,str,1))//每次读一行
            {
                if(str[0] =='
    ')
                {
                    printf("
    ");
                    break;
                }
                printf("%c",str[0]);
            }
            page_now = lseek(fd, 0, SEEK_CUR);//实时更新已读行数
            if( page_num == PAGENUM )
            {
                rel = see_more( page_sum, page_now);//获取用户输入
                printf("33[1A33[K");//将光标上移一行,并清空该行内容,用以覆盖提示信息
                if( rel == 0 )
                {
                    break;
                }
                else
                {
                    page_num -= rel;
                }
            }
            page_num++;
        }
    }
    
    int see_more(int sum,int now)
    {
        int rel;
        printf("33[7m --很多其它-- enter翻行 backspace翻页 q退出  %.2f%% 33[0m",now*100.0/sum);//反显输出提示信息以及文件已读比例
    
        while(rel = getchar())
        {
            if(rel == 'q')
            {
                return 0;
            }
            if(rel == ' ')
            {
                return PAGENUM;
            }
            if(rel == '
    ')
            {   
                return 1;
            }
        }
    
        return 0;
    }
  • 相关阅读:
    Git 总结
    .net报错大全
    对于堆和栈的理解
    html 局部打印
    c#面试问题总结
    算法题总结
    h5-plus.webview
    堆和栈,引用类型,值类型,指令,指针
    .NET framework具体解释
    前端之间的url 传值
  • 原文地址:https://www.cnblogs.com/llguanli/p/7324412.html
Copyright © 2011-2022 走看看