/*
浏览单个文件,按行或者按字节
格式: tail filename c/n num,目前不支持其他格式
*/
#include
#include
#include
#include
/*
错误处理
*/
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
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
num = n + num;
if (num
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
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);
}
}
总结:
目前未实现其他功能
原文:http://my.oschina.net/u/2313065/blog/474539