/* 浏览单个文件,按行或者按字节 格式: tail filename c/n num,目前不支持其他格式 */ #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> /* 错误处理 */ void oops(char *s1, char* s2) { fprintf(stderr, "Error:%s", s1); perror(s2); exit(1); } /* 按字节输出,name打开文件名,命令行字节数 */ void print_c(char* name, int num) { char buf[200]; int fd, n; long size; fd = open(name, O_RDONLY); if (fd == -1) oops("can‘t open", name); size = lseek(fd, 0, SEEK_END); if (num < 0) if (-num >= size) lseek(fd, 0, SEEK_SET); else lseek(fd, num, SEEK_END); else if (num >= size) lseek(fd, 0, SEEK_END); else lseek(fd, num, SEEK_SET); while (( n = read(fd, buf, 200)) > 0) if (write(STDOUT_FILENO, buf, n) != n) oops("write failed", "stdout"); if (n == -1) oops("read failed", "input"); close(fd); } /* 按行输出,name文件名,num命令行行数 按行输出,方法效率较低,先遍历文件统计所以行数,再确定输出位置 */ void print_n(char *name, int num) { char buf[200]; FILE *fp; int n = 0; fp = fopen(name, "r"); while (fgets(buf, 200, fp) != NULL) n++; rewind(fp); if (num < 0) num = n + num; if (num < 0) num = 0; while(num--) fgets(buf, 200, fp); while (1) { if (fgets(buf, 200, fp) == NULL) break; if (fputs(buf, stdout) == EOF) oops("write failed", "stdout"); } fclose(fp); } int main(int argc, char* argv[]) { int num; FILE *fp; char cmd; if (argc < 3) { fprintf(stderr, "tail01: missing operand"); exit(1); } if (argv[2][0] == ‘c‘ || argv[2][0] == ‘n‘) cmd = argv[2][0]; else { fprintf(stderr, "operand error"); exit(1); } num = atoi(argv[3]); if (argv[3][0] != ‘+‘&&argv[3][0] != ‘-‘) num = -num; switch(cmd) { case ‘c‘: print_c(argv[1], num); break; case ‘n‘: print_n(argv[1], num); break; default: fprintf(stderr, "switch eror"); exit(1); } }
总结:
目前未实现其他功能
时间: 2024-10-02 21:48:45