自己编写more命令
来源:互联网 发布:mac搜狗输入法怎么设置 编辑:程序博客网 时间:2024/05/22 03:12
more命令可以实现的功能是很丰富的,包括模式查找。今天我们只是实现它的一个基本功能:
- more 文件列表
- 在屏幕正文显示已读的百分比
- 按下回车显示下一行
- 按下空格显示下一屏
- 按下q退出
- 按回车、空格、q时没有回显
这里有几个问题:
- 要在屏幕正文显示已读的百分比,那我们必须先获取文件列表中各个文件的长度,这个可以使用系统调用lstat
#include<sys/stat.h>
struct stat *buf;
lstat("filename",buf) //获取文件状态
filesize+=buf->st_size; //获取文件大小 - 要显示整屏内容,我们就需要知道一屏可以显示多少行,然后从文件中读出这么多行显示在屏幕上。
#include<termios.h>
struct winsize *ws;
ws=(struct winsize*)malloc(sizeof(struct winsize));
memset(ws,0x00,sizeof(struct winsize));
ioctl(STDIN_FILENO,TIOCGWINSZ,ws);
int width=ws->ws_col;
int height=ws->ws_row; - 禁用回显
#include<termios.h>
struct termios ts; //终端属性
tcgetattr(STDIN_FILENO,&ts); //获取终端属性
ts.c_lflag &= (~ECHO); //阻止回显
tcsetattr(STDIN_FILENO,TCSAFLUSH,&ts); //设置终端的新属性 - 从终端读取单个字符后立即返回,不需要按回车
#include<termios.h>
struct termios ts; //终端属性
tcgetattr(STDIN_FILENO,&ts); //获取终端属性
ts.c_lflag &= (~ICANON); //设置终端为非标准模式
ts.c_cc[VMIN]=1; //这两行当需要从终端获取字符时立即返回,不需要按回车键
ts.c_cc[VTIME]=0;
tcsetattr(STDIN_FILENO,TCSAFLUSH,&ts); //设置终端的新属性
完整代码:
#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>void gettermsize(int *w,int *h); //获取终端尺寸void do_more(FILE *); //根据see_more获取的用户输入,显示更多的文件内容或退出int see_more(); //捕获用户的输入指令void settermattr(); //设置终端属性int width; //终端屏幕宽度int height; //终端屏幕高度int filesize; //文件的大小int readsize; //已经显示的内容长度struct termios ts,ots; //终端属性int main(int argc,char *argv[]){ gettermsize(&width,&height); settermattr(); FILE *fp; struct stat *buf; filesize=0; readsize=0; buf=(struct stat*)malloc(sizeof(struct stat)); memset(buf,0x00,sizeof(struct stat)); if(argc==1) //如果没有指定文件,则从标准输入读取内容 do_more(stdin); else{ //从文件列表中读取内容 int i; for(i=1;i<argc;i++){ //more命令后面可能跟多个文件 if((fp=fopen(*(argv+i),"r"))!=0){ //以只读形式打开文件 if(lstat((const char*)*(argv+i),buf)==0){ //获取文件状态 filesize+=buf->st_size; //获取文件大小 printf("fs=%ld\n",buf->st_size); } else{ exit(1); } fclose(fp); //关闭文件 } else{ //打开文件失败,退出程序 exit(1); } } printf("size=%d\n",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); return 0;}void gettermsize(int *w,int *h){ struct winsize *ws; ws=(struct winsize*)malloc(sizeof(struct winsize)); memset(ws,0x00,sizeof(struct winsize)); ioctl(STDIN_FILENO,TIOCGWINSZ,ws); *w=ws->ws_col; *h=ws->ws_row;}void settermattr(){ 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}void do_more(FILE *fp){ int linesize=width; char line[linesize]; int num_of_lines=0; //记录本次读了多少行 int reply; //记录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++; }}int see_more(){ int c; printf("\033[7m--more--(%2.0f%%)\033[m",(double)readsize/filesize*100); while((c=getc(stdin))!=EOF){ //注意加括号,赋值操作符是右结合的。如果不加括号会把getchar()!=EOF的结果赋给c if(c=='q'){ return 0; } if(c==' ') //空格 return height; if(c=='\n') //回车 return 1; } return 0;}
- 自己编写more命令
- 自己编写more命令
- 自己编写more命令
- 自己编写的more命令
- 自己的more命令code
- 自己编写who命令
- 自己编写ls命令
- Linux_自己写一个more命令
- 编写自己的who命令
- Linux实习——more命令的编写
- more命令
- more命令
- more命令
- more命令
- more命令
- more命令
- more命令
- more命令
- 进程间通讯-跨进程函数调用
- freemaker基本测试和辅助类
- Implementing the Singleton Pattern in C#
- mktime返回-1的原因
- TC SRM 562 DIV 2
- 自己编写more命令
- poj 1990 两颗树状数组
- 详解80x86架构处理器寄存器
- 从外网通过路由器ping内网IP的方法
- IOS 中两种传值方式:单例模式和delegate
- 一分钟先生: 程序员面试真经
- VS2010、SQL Server 2008和SQL Server 2012安装详解
- 虽然开始错了,但还是解决了
- 现代软件工程里的困惑