tac 命令的实现

tac 命令的模拟实现

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

清单 4. tac 命令实现代码

#include
#include
#include
#include
#include
#include
#include
#include
#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'中的下一个字符开始的字符串,也就刚好是一行文本。

·最后当从后向前找到第一个换行字符时,打印第一行,程序结束。


相关内容