zoukankan      html  css  js  c++  java
  • head/tail实现

         只实现了head/tail的基本功能,默认显示十行及-n参数。
         
      一、使用带缓冲的系统调用。
         
      write/read等系统调用是不带缓冲的,可以包装一层,使其带缓冲。
    typedef struct
    {
        int rio_fd;
        int rio_cnt;
        char *rio_bufptr;
        char rio_buf[RIO_BUFFSIZE];
    }rio_t;
     
    void rio_readinitb(rio_t *rp, int fd)
    {
        rp->rio_fd = fd;
        rp->rio_cnt = 0;
        rp->rio_bufptr = rp->rio_buf;
    }
     
    ssize_t rio_read(rio_t *rp, void *usrbuf, size_t n)
    {
        int cnt = 0;
     
        while (rp->rio_cnt <= 0)
        {
            if ((rp->rio_cnt = read(rp->rio_fd, rp->rio_buf, sizeof(rp->rio_buf))) < 0)
            {
                if (errno != EINTR)
                {
                    return -1;
                }
            }
            else if (rp->rio_cnt == 0)
            {
                return 0;
            }
            else
            {
                rp->rio_bufptr = rp->rio_buf;
            }
        }
     
        //cnt = n > rp->rio_cnt?rp->rio_cnt:n;
     
        cnt = n;
        if (n > rp->rio_cnt)
        {
            cnt = rp->rio_cnt;
        }
     
        memcpy(usrbuf, rp->rio_bufptr, cnt);
        rp->rio_cnt -= cnt;
        rp->rio_bufptr += cnt;
     
        return cnt;
    }
     
    ssize_t rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen, int count)
    {
        int i = 0, rc = 0, num = 0;
        char c = 0, *buf = usrbuf;
     
        lseek(rp->rio_fd, maxlen, SEEK_END);
     
        for (i = 1; i < maxlen; i++)
        {
            if ((rc = rio_read(rp, &c, 1)) == 1)
            {
                *buf++ = c;
                if (c == '
    ')
                {
                    if (++num == count)
                    {
                        break;
                    }
                }
            }
            else if (rc == 0)
            {
                if (i == 1)
                {
                    return 0;
                }
                else
                {
                    break;
                }
            }
            else
            {
                return -1;
            }
        }
     
        *buf = '';
        return i;
    }
    View Code

         二、head命令实现

    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <string.h>
    #include "rio.h"
     
    #define MAXSIZE 4096
     
    int main(int argc, char **argv)
    {
        if (argc < 2)
        {
            fprintf(stderr, "usage %s [-n n] filename
    ", argv[0]);
            return -1;
        }
     
        int times = 10, i = 0, in_fd = -1, n_char = 0;
        char filename[16] = {0};
        char buf[MAXSIZE] = {0};
        rio_t rio_buf = {0};
     
        for (i = 1; i < argc; i++)
        {
            if (!strcmp(argv[i], "-n"))
            {
                times = atoi(argv[++i]);
            }
            else
            {
                snprintf(filename, sizeof(filename), "%s", argv[i]);
            }
        }
     
        if ((in_fd = open(filename, O_RDONLY)) == -1)
        {
            fprintf(stderr, "open %s failed
    ", filename);
            return -1;
        }
     
        rio_readinitb(&rio_buf, in_fd);
        if ((n_char = rio_readlineb(&rio_buf, buf, MAXSIZE, times)) > 0)
        {
            write(STDOUT_FILENO, buf, n_char);
        }
     
        close(in_fd);
     
        return 0;
    }
    View Code

         三、tail命令实现

    #include "rio.h"
     
    #define MAXSIZE 4096
     
    void show_info(char *buf, char **ptr, int count);
     
    int main(int argc, char **argv)
    {
        if (argc < 2)
        {
            fprintf(stderr, "usage %s [-n n] filename
    ", argv[0]);
            return -1;
        }
     
        int times = 10, i = 0, in_fd = -1;
        char filename[16] = {0};
        char buf[MAXSIZE] = {0};
        rio_t rio_buf = {0};
        char *ptr[MAXSIZE];
     
        for (i = 1; i < argc; i++)
        {
            if (!strcmp(argv[i], "-n"))
            {
                times = atoi(argv[++i]);
            }
            else
            {
                snprintf(filename, sizeof(filename), "%s", argv[i]);
            }
        }
     
        if ((in_fd = open(filename, O_RDONLY)) == -1)
        {
            fprintf(stderr, "open %s failed
    ", filename);
            return -1;
        }
     
        rio_readinitb(&rio_buf, in_fd);
        rio_read(&rio_buf, buf, MAXSIZE);
     
        show_info(buf, ptr, times);
     
        return 0;
    }
     
    void show_info(char *buf, char **ptr, int times)
    {
        int num = 0;
        int flag = 0;
     
        if (num < times)
        {
            *ptr = strrchr(buf, '
    ');
            flag = 1;
            **ptr = '';
            show_info(buf, ptr + 1, --times);
        }
     
        if (flag)
        {
            printf("%s
    ", *ptr + 1);
        }
    }
    View Code

         通过递归show_info来实现按顺序打印,其实也可以用链表来实现,不过递归写起来简单。

  • 相关阅读:
    关于response.getWriter()写回数据的实际发生时间点
    警惕多iframe下的同名id引起的诡异问题
    spring注入静态成员变量提示invalid setter method
    plsql+绿色版oracle连接远程数据库配置及提示缺少msvcr71.dll解决方法
    <mvc:default-servlet-handler/>导致SimpleUrlHandlerMapping失效
    maven项目下jsp文件中el表达式失效问题
    Python爬虫框架Scrapy实例(三)数据存储到MongoDB
    Python爬虫实例(五) requests+flask构建自己的电影库
    MySQL与Python交互
    Python爬虫基础(四)Requests库的使用
  • 原文地址:https://www.cnblogs.com/shenlinken/p/5828253.html
Copyright © 2011-2022 走看看