仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 618|回复: 11
打印 上一主题 下一主题

[其他Linux] Linux设计本人编写more命令仓酷云

[复制链接]
因胸联盟 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:29:03 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
Linux的常用命令find,察看man文档,初学者一定会觉得太复杂而不原意用,但是你一旦学会就爱不释手。
more命令能够完成的功效是很丰厚的,包含形式查找。明天我们只是完成它的一个基础功效:

  • more文件列表
  • 在屏幕注释显现已读的百分比
  • 按下回车显现下一行
  • 按下空格显现下一屏
  • 按下q加入
  • 按回车、空格、q时没有回显
这里有几个成绩:

  • 要在屏幕注释显现已读的百分比,那我们必需先猎取文件列表中各个文件的长度,这个可使用体系挪用lstat
    #include<sys/stat.h>
    structstat*buf;
    lstat("filename",buf)//猎取文件形态
    filesize+=buf->st_size;//猎取文件巨细
  • 要显现整屏内容,我们就必要晓得一屏能够显现几行,然后从文件中读出这么多行显现在屏幕上。
    #include<termios.h>
    structwinsize*ws;
    ws=(structwinsize*)malloc(sizeof(structwinsize));
    memset(ws,0x00,sizeof(structwinsize));
    ioctl(STDIN_FILENO,TIOCGWINSZ,ws);
    intwidth=ws->ws_col;
    intheight=ws->ws_row;

  • 禁用回显
    #include<termios.h>
    structtermiosts;//终端属性
    tcgetattr(STDIN_FILENO,&ts);//猎取终端属性
    ts.c_lflag&=(~ECHO);//制止回显
    tcsetattr(STDIN_FILENO,TCSAFLUSH,&ts);//设置终真个新属性

  • 从终端读取单个字符后当即前往,不必要按回车
    #include<termios.h>
    structtermiosts;//终端属性
    tcgetattr(STDIN_FILENO,&ts);//猎取终端属性
    ts.c_lflag&=(~ICANON);//设置终端为非尺度形式
    ts.c_cc[VMIN]=1;//这两行当必要从终端猎取字符时当即前往,不必要按回车键
    ts.c_cc[VTIME]=0;
    tcsetattr(STDIN_FILENO,TCSAFLUSH,&ts);//设置终真个新属性
完全代码:
  1. #include<stdio.h>#include<sys/ioctl.h>#include<fcntl.h>#include<unistd.h>#include<sys/types.h>#include<sys/stat.h>#include<stdlib.h>#include<string.h>#include<termios.h>voidgettermsize(int*w,int*h);//猎取终端尺寸voiddo_more(FILE*);//依据see_more猎取的用户输出,显现更多的文件内容或加入intsee_more();//捕捉用户的输出指令voidsettermattr();//设置终端属性intwidth;//终端屏幕宽度intheight;//终端屏幕高度intfilesize;//文件的巨细intreadsize;//已显现的内容长度structtermiosts,ots;//终端属性intmain(intargc,char*argv[]){gettermsize(&width,&height);settermattr();FILE*fp;structstat*buf;filesize=0;readsize=0;buf=(structstat*)malloc(sizeof(structstat));memset(buf,0x00,sizeof(structstat));if(argc==1)//假如没有指定文件,则从尺度输出读取内容do_more(stdin);else{//从文件列表中读取内容inti;for(i=1;i<argc;i++){//more命令前面大概跟多个文件if((fp=fopen(*(argv+i),"r"))!=0){//以只读情势翻开文件if(lstat((constchar*)*(argv+i),buf)==0){//猎取文件形态filesize+=buf->st_size;//猎取文件巨细printf("fs=%ld
  2. ",buf->st_size);}else{exit(1);}fclose(fp);//封闭文件}else{//翻开文件失利,加入程序exit(1);}}printf("size=%d
  3. ",filesize);for(i=1;i<argc;i++){//more命令前面大概跟多个文件if((fp=fopen(*(argv+i),"r"))!=0){//以只读情势翻开文件do_more(fp);//显现文件内容fclose(fp);//封闭文件}else{//翻开文件失利,加入程序exit(1);}}}tcsetattr(STDIN_FILENO,TCSANOW,&ots);return0;}voidgettermsize(int*w,int*h){structwinsize*ws;ws=(structwinsize*)malloc(sizeof(structwinsize));memset(ws,0x00,sizeof(structwinsize));ioctl(STDIN_FILENO,TIOCGWINSZ,ws);*w=ws->ws_col;*h=ws->ws_row;}voidsettermattr(){tcgetattr(STDIN_FILENO,&ts);//猎取终端属性ots=ts;//备份终端属性ts.c_lflag&=(~ECHO);//制止回显ts.c_lflag&=(~ICANON);//设置终端为非尺度形式ts.c_cc[VMIN]=1;//这两行当必要从终端猎取字符时当即前往,不必要按回车键ts.c_cc[VTIME]=0;tcsetattr(STDIN_FILENO,TCSAFLUSH,&ts);//设置终真个新属性。TCSAFLUSH暗示输入行列空了今后才失效,失效之前的输入行列被flush}voiddo_more(FILE*fp){intlinesize=width;charline[linesize];intnum_of_lines=0;//纪录本次读了几行intreply;//纪录see_more()的前往值FILE*fp_tty;while(fgets(line,linesize,fp)){//从文件中读取一行内容readsize+=strlen(line);//读出的内容长度if(num_of_lines==height){//假如满屏了reply=see_more();//从键盘猎取用户输出的命令if(reply==0){//用户不必要显现更多内容了,要加入tcsetattr(STDIN_FILENO,TCSANOW,&ots);exit(0);}num_of_lines-=reply;}if(fputs(line,stdout)==EOF){//把这行内容显现在用户屏幕上tcsetattr(STDIN_FILENO,TCSANOW,&ots);//TCSANOW暗示修正当即失效perror("fputs");exit(1);}num_of_lines++;}}intsee_more(){intc;printf("\033[7m--more--(%2.0f%%)\033[m",(double)readsize/filesize*100);while((c=getc(stdin))!=EOF){//注重加括号,赋值操纵符是右分离的。假如不加括号会把getchar()!=EOF的了局赋给cif(c==q){return0;}if(c==)//空格returnheight;if(c==
  4. )//回车return1;}return0;}
复制代码
Linux的常用命令find,察看man文档,初学者一定会觉得太复杂而不原意用,但是你一旦学会就爱不释手。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-5-20 08:36

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表