linux编程实践2(实现more命令)

6 篇文章 0 订阅

好久没有C语言编程了,最近看了下linux编程实践这本书,就将书上的程序练习下,下面是简单实现命令more的代码,如回车查看下一行,空格查看下一页,q退出,不完善的地方请指出。编译后,在linux命令行输入 ./progrom(编译后的程序) filename(要查看的文件),即可查看文件内容。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<termios.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/ioctl.h>

#define PAGELEN 24
#define LINELEN 512

void do_more(FILE *);
int see_more(FILE *, double);
off_t get_file_size(int);
int get_term_size();

int line_size;

int main(int argc, char **argv)
{
    line_size = get_term_size();
    FILE *fp;
    if(argc == 1)
        do_more(stdin);


    while(--argc)
    {
        if((fp = fopen(*++argv, "r")) != NULL)
        {
            do_more(fp);
            fclose(fp);
        }
        else
            exit(1);
    }
    return 0;
}

int get_term_size()
{
    struct winsize sz;
    ioctl(STDOUT_FILENO, TIOCGWINSZ, &sz);
    line_size = sz.ws_row;
    return line_size;
}

off_t get_file_size(int fd)
{
    struct stat file_info;
    off_t file_size;
    if(fstat(fd, &file_info) == -1)
        exit(1);
    file_size = file_info.st_size;

    return file_size;
}

void do_more(FILE *fp)
{
    char line[LINELEN];
    memset(line, 0, LINELEN);
    int num_of_lines = 0, reply, fd, file_no;
    double percent;
    off_t file_size, total_size = 0;
    FILE *fp_tty;
    if((fp_tty = fopen("/dev/tty", "r")) == NULL)
        exit(1);
    //get file descriptor form file stream
    fd = fileno(fp);
    file_no = fileno(fp_tty);
    //get file size according the fd
    file_size = get_file_size(fd);

    //set the termios to disable the character echo function
    struct termios new_setting, init_setting;
    if(tcgetattr(file_no, &init_setting) == -1)
        exit(1);
    new_setting = init_setting;
    new_setting.c_lflag &= ~(ECHO | ICANON);
    tcsetattr(file_no, TCSANOW, &new_setting);
    while(fgets(line, LINELEN, fp))
    {
        total_size += strlen(line);
        percent = (double)total_size / file_size * 100;
        if(num_of_lines == PAGELEN)
        {
            reply = see_more(fp_tty, percent);
            printf("\33[13D");
            printf("\33[K");
            if(reply == 0)
                break;
            num_of_lines -= reply;
        }


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


    }
    //set the default buffer and terminal setting
    tcsetattr(file_no, TCSANOW, &init_setting);
}

int see_more(FILE *fp, double percent)
{
    int c;
    printf("\033[7m--More--(%%%03.0f%%)\033[0m", percent);


    while((c = getc(fp)) != EOF)
    {
        if(c == ' ')
            return  PAGELEN;
        if(c == '\n')
            return 1;
        if(c == 'q')
            return 0;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值