为了加深一下对linux下常规命令的理解顺带写作业,就用c语言模拟了一下tail命令。
首先简单介绍一下tali命令的用法。
tail test.txt:显示test.txt文件的最后十行
tail -n 5 test.txt:显示test.txt文件最后五行
当然tail命令还有tail -f 这个用法,用于实时更新文件的最后十行,不过为了偷懒就没写了,思路差不多,只是需要隔一段时间重新刷新一下。
同时,如果后面给的文件路径或者文件名等写错了,或者写的参数不正确,导致参数错误或文件找不到的话,也会有提示信息。
作为小白,下面写的内容只要会c语言基本语法就能看懂,不会的地方我均写了解释或者放上了参考文档。
![这里写图片描述 linux下使用c语言模拟tail [-n] 命令_tail](https://s2.51cto.com/images/blog/202210/31180004_635f9ca47f71461705.gif)
废话不多说,开始讲解思路:
1、初始化默认读取长度line=10,如果使用了-n参数设置了长度为x,那么就让line=x
2、一行一行读取文件并保存在数组。但是我是模拟了一下循环数组,即当数组长度达到line了就将数组下一次写入的位置下标设置为0,这样在一定程度上保证了不会因为文件太大而溢出。
举个例子:假如文件一共15行,保存文件每一行数据的数组为char buffer[][],第0-9行存放在buffer[0][] - buffer[9][] 之中,但是第10行数据又会被保存到buffer[0][]中,因为最后只需要输出10行即可,所以只需要保存距离当前位置的最后十行。不过为了输出时候保证位置正确,肯定是要记录数组下标的。
3、开始输出了,输出是对buffer数组进行循环遍历,循环的次数等于min(line,文章行数)。
然后从前面保存的下标开始输出即可。
![这里写图片描述 linux下使用c语言模拟tail [-n] 命令_tail_02](https://s2.51cto.com/images/blog/202210/31180004_635f9ca47ee2571140.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=,x-oss-process=image/resize,m_fixed,w_1184)
思路清晰了,就到了具体实现中存在的问题了。
首先,main函数的参数是什么意思?
然后,既然需要读取-n 5 文件路径 这些信息,而且并不知道-n 5这样的参数是否会存在,如何解决?
再之后,如何一行一行读取文件?
有两个思路,使用read,或者是用fgets。我们要求是使用read的,但是太麻烦了,我偷懒就还是使用fgets了。下面先简要介绍一下用read实现的思路:
想了解一下read的童鞋请参考:
![这里写图片描述 linux下使用c语言模拟tail [-n] 命令_linux_03](https://s2.51cto.com/images/blog/202210/31180004_635f9ca48682710981.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=,x-oss-process=image/resize,m_fixed,w_1184)
read的配套用法——open详解
read的用法详解
1) 定义一个缓冲区,用read将文件全部存入缓冲区再通过\n来识别换行。明显的一个缺陷就是当文件太大的时候缓冲区会存不下,浪费了存储空间。
2) 每次读一个字符,然后保存到一个临时缓冲队列里,读取到第一个\n后将缓冲队列里的数据当成一行存储。缺点在于效率低下。
这两种思路是在一个论坛里总结出来的,论坛链接
总之使用read是很麻烦的一件事
,所以接下来还是老实使用fgets吧。
这个就很简单啦,参考:fgets读取文件
可运行源代码
最后就是我的源码咯,头文件可能多了点,因为原来使用read加上去的,但是嫌read太麻烦还是改成fgets了。
运行如图:
![这里写图片描述 linux下使用c语言模拟tail [-n] 命令_linux_04](https://s2.51cto.com/images/blog/202210/31180004_635f9ca49c2c569318.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=,x-oss-process=image/resize,m_fixed,w_1184)
![这里写图片描述 linux下使用c语言模拟tail [-n] 命令_模拟tail_05](https://s2.51cto.com/images/blog/202210/31180004_635f9ca49d36196900.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=,x-oss-process=image/resize,m_fixed,w_1184)
















