只实现了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 = ;
rp->rio_bufptr = rp->rio_buf;
} ssize_t rio_read(rio_t *rp, void *usrbuf, size_t n)
{
int cnt = ; while (rp->rio_cnt <= )
{
if ((rp->rio_cnt = read(rp->rio_fd, rp->rio_buf, sizeof(rp->rio_buf))) < )
{
if (errno != EINTR)
{
return -;
}
}
else if (rp->rio_cnt == )
{
return ;
}
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 = , rc = , num = ;
char c = , *buf = usrbuf; lseek(rp->rio_fd, maxlen, SEEK_END); for (i = ; i < maxlen; i++)
{
if ((rc = rio_read(rp, &c, )) == )
{
*buf++ = c;
if (c == '\n')
{
if (++num == count)
{
break;
}
}
}
else if (rc == )
{
if (i == )
{
return ;
}
else
{
break;
}
}
else
{
return -;
}
} *buf = '\0';
return i;
}

二、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 < )
{
fprintf(stderr, "usage %s [-n n] filename\n", argv[]);
return -;
} int times = , i = , in_fd = -, n_char = ;
char filename[] = {};
char buf[MAXSIZE] = {};
rio_t rio_buf = {}; for (i = ; 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)) == -)
{
fprintf(stderr, "open %s failed\n", filename);
return -;
} rio_readinitb(&rio_buf, in_fd);
if ((n_char = rio_readlineb(&rio_buf, buf, MAXSIZE, times)) > )
{
write(STDOUT_FILENO, buf, n_char);
} close(in_fd); return ;
}

三、tail命令实现

#include "rio.h"

#define MAXSIZE 4096

void show_info(char *buf, char **ptr, int count);

int main(int argc, char **argv)
{
if (argc < )
{
fprintf(stderr, "usage %s [-n n] filename\n", argv[]);
return -;
} int times = , i = , in_fd = -;
char filename[] = {};
char buf[MAXSIZE] = {};
rio_t rio_buf = {};
char *ptr[MAXSIZE]; for (i = ; 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)) == -)
{
fprintf(stderr, "open %s failed\n", filename);
return -;
} rio_readinitb(&rio_buf, in_fd);
rio_read(&rio_buf, buf, MAXSIZE); show_info(buf, ptr, times); return ;
} void show_info(char *buf, char **ptr, int times)
{
int num = ;
int flag = ; if (num < times)
{
*ptr = strrchr(buf, '\n');
flag = ;
**ptr = '\0';
show_info(buf, ptr + , --times);
} if (flag)
{
printf("%s\n", *ptr + );
}
}

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

head/tail实现的更多相关文章

  1. REDHAT一总复习1 输出重定向及head tail的用法

    1.使用bash命令,在server机上完成以下任务.(考点是:head  tail的使用) .显示/usr/bin/clean-binary-files文件的前12行,并将其输出到/home/stu ...

  2. tail命令详解

    搜索 纠正错误  添加实例 tail 在屏幕上显示指定文件的末尾若干行 补充说明 tail命令 用于输入文件中的尾部内容.tail命令默认在屏幕上显示指定文件的末尾10行.如果给定的文件不止一个,则在 ...

  3. Linux命令详解之—tail命令

    tail命令也是一个非常常用的文件查看类的命令,今天就为大家介绍下Linux tail命令的用法. 更多Linux命令详情请看:Linux命令速查手册 Linux tail命令主要用来从指定点开始将文 ...

  4. linux命令之tail

    tail用于输出文件末尾部分.一个比较有用的功能是tail + grep实现类似于安卓开发时调试使用的logcat,具体操作是: 一般我是用SecureCRT连接linux,然后使用SecureCRT ...

  5. PHP实现linux命令tail -f

    PHP实现linux命令tail -f 今天突然想到之前有人问过我的一个问题,如何通过PHP实现linux中的命令tail -f,这里就来分析实现下. 这个想一想也挺简单,通过一个循环检测文件,看文件 ...

  6. tail -f 和 -F 的用法

    tail -f 和 -F 的用法  Tai 2010-08-16 16:03:18 -f 是--follow[=HOW]的缩写, 可以一直读文件末尾的字符并打印出来."[=HOW]" ...

  7. scala tail recursive优化,复用函数栈

    在scala中如果一个函数在最后一步调用自己(必须完全调用自己,不能加其他额外运算子),那么在scala中会复用函数栈,这样递归调用就转化成了线性的调用,效率大大的提高.If a function c ...

  8. linux head、tail、sed、cut、grep、find

    head用法: head 参数 文件名 -cn:显示前n个字节    -n:显示前n行 例子:head -c20 1.txt 显示1.txt文件中前20个字符 ls |  head -20:显示前20 ...

  9. linux命令每日一练习-tail

    tail 是查看文件的末尾 tail -n 5*** 显示文件×××的最后5行 tail -n +5 ××× 显示文件×××从第5行开始的内容 tail -f *** 监视文件×××的末尾.循环展示

随机推荐

  1. ArtifactTransferException: Failure to transfer org.apache.openejb:javaee-api:jar:5.0-1

    最近在myeclipse上创建maven类型的web项目的时候,出现了一个错误. ArtifactTransferException: Failure to transfer org.apache.o ...

  2. js变量声明作用域问题

    1.先来看两个题 var a = 1; foo1(); function foo1(){ console.log(a); //输出1 }; foo2(); var a = 1; function fo ...

  3. JavaScript随笔6

    Ajax:(1) 阻止缓存?+t = new data(); eval可以把string变为数组(2) get:放入URL username = &password = ; 容量有小 安全性差 ...

  4. .net中 页面包含子页面 类似include的功能--(记录九)

    aspx页面中: //加上这一段代码 <%@ Register Tagprefix="ImgEvaTask" TagName="content1" src ...

  5. 【JS】javascript 正则表达式 大全 总结

    javascript 正则表达式 大全 总结 参考整理了一些javascript正则表达式 目的一:自我复习归纳总结 目的二:共享方便大家搜索 微信:wixf150 验证数字:^[0-9]*$ 验证n ...

  6. iOS 支持 IPv6

    苹果的规定:2016年6月1日提交到App Store必须支持IPv6-only网络. 官方文档:https://developer.apple.com/library/mac/documentati ...

  7. ASP.NET MVC5+EF6+EasyUI 后台管理系统(53)-工作流设计-我的批阅

    系列目录 前言:由于工作原因工作流一直没时间更新,虽然没有更新,但是批阅和申请差不多,改变一下数据的状态字段就行,有几个园友已经率先完成了 说句实话,一个工作流用文章表达很难,我起初以为这是一个很简单 ...

  8. 基于hexo+github搭建一个独立博客

    一直听说用hexo搭建一个拥有自己域名的博客是很酷炫的事情~,在这十一花上半个小时整个hexo博客岂不美哉. 使用Hexo吸引我的是,其简单优雅, 而且风格多变, 适合程序员搭建个人博客,而且支持多平 ...

  9. go语言注释

    Go语言注释实例代码教程 - Go支持C语言风格的/* */块注释,也支持C++风格的//行注释. 当然,行注释更通用,块注释主要用于针对包的详细说明或者屏蔽大块的代码. 每个包都应有一个包注解,即 ...

  10. 『.NET Core CLI工具文档』(六)dotnet 命令

    说明:本文是个人翻译文章,由于个人水平有限,有不对的地方请大家帮忙更正. 原文:dotnet command 翻译:dotnet 命令 名称 dotnet -- 运行命令行命令的一般驱动程序 概要 d ...