Linux 下几个文件操作命令的代码实现(3)

tac 命令的实现

tac 命令的模拟实现

tac 命令主要用来以倒序的方式显示一个文本文件的内容,也就是先显示最后一行的内容,最后显示第一行的内容。代码如下:


清单 4. tac 命令实现代码
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #define SIZE 1000001 #define NLINE '\n' int main(int argc , char *argv[]){ char buf[SIZE]; char *p1,*p2,*p3,*p4; struct stat *fp; int fd; fp=(struct stat *)malloc(sizeof(struct stat)); if(argc != 2){ fprintf(stderr,"input error %s \n"); exit(1); } if( (fd=open(argv[1],O_RDONLY)) == -1 ){ fprintf(stderr,"open error %s \n",strerror(errno)); exit(1); } if(fstat(fd,fp)== -1){ fprintf(stderr,"fstat error %s \n",strerror(errno)); exit(2); } if(fp->st_size > (SIZE-1)){ fprintf(stderr,"buffer size is not big enough \n"); exit(3); } if(read(fd,buf,fp->st_size) == -1){ fprintf(stderr,"read error.\n"); exit(4); } p1=strchr(buf,NLINE); p2=strrchr(buf,NLINE); *p2='\0'; do{ p2=strrchr(buf,NLINE); p4=p2; p3=p2+sizeof(char); printf("%s\n",p3); *p4='\0'; }while(p2 != p1); if(p2 == p1){ *p2 = '\0'; printf("%s\n",buf); } return 0; }  

让我们来运行一下该程序:

程序的运行情况如下,假设编译后的可执行文件名为 emulatetac,有一个文本文件 test.txt。

# gcc emulatetac.c -o emulatetac # cat test.txt 1 2 3 a b # ./emulatetac test.txt b a 3 2 1  

可以看出文件内容以倒序方式显示输出了。

tac 命令实现的说明

下面逐行讲解:

#include 的头文件,都应该通过 man 2 系统调用命令来查找,这里就不多说了。 下面定义了一个宏常量 SIZE,该常量主要用来表示能够读入最大多少个字节的文件,当文件过大的时候程序就不执行,直接退出。然后定义了宏常量 NLINE 表示换行符'\n'。 接下来主程序体开始了:首先定义一个字符数组 buf,用来把读入文件的每个字节都存在该数组里面。 然后定义了 4 个字符串指针,一个指向结构体 struct stat 的指针 fp,一个文件描述符。 然后为指向结构体的指针 fp 分配存储空间。 接下来判断输入参数是否为 2 个,也就是命令本身和文件名。不是 2 个就直接退出。 然后以只读方式打开输入文件名的文件,也就是 test.txt。打开成功的话,把打开的文件赋值到文件描述符 fd 中,错误的话退出。 然后用 fstat 系统调用把文件描述符 fd 中对应文件的元信息,存放到结构体指针 fp 指向的结构中。 下面判断当文件的大小超过缓冲区数组 buf 的大小 SIZE-1 时,就退出。 下面将把文件 test.txt 中的每个字符存放到数组 buf 中。 下面是程序的核心部分:首先我们找到字符串 buf 中的第一个换行字符存放到 p1 指针里面,然后把最后一个换行字符置为字符串结束符。 接下来我们从后往前查找字符串 buf 中的换行符,直到遇到第一个换行符 p1。同时打印每个找到的换行符'\n'中的下一个字符开始的字符串,也就刚好是一行文本。 最后当从后向前找到第一个换行字符时,打印第一行,程序结束。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/24756.html