我需要帮助了解如何使用tail
和fseek()
的组合在c中实现linux getline
命令。
我正在使用fseek()
到达文件末尾,然后使用while循环向后迭代。
如果检测到换行符('\ n')。我打印出该行,然后返回到我调用getline
之前已到达的位置减去检测到'\ n'的位置。
否则如果没有检测到'\ n',那么使用我当前位置的偏移量-2将向后迭代。
我知道有更简单的方法来执行涉及缓冲区的tail命令,但我的算法是否正确?如果是这样,实施它的最佳方式是什么。
提前致谢。
void tail(FILE *ifp, int k) {
int line_count=0;
char *line=NULL;
size_t len=0;
//go to end of file
if(fseek(ifp,-1,SEEK_END)) {
fprintf(stderr,"Failure in reaching end of file\n");
}
//while loop which will iterate backward starting at the end of file until line_count = k.
while(line_count != k) {
//if detected a newline character, increment line_count, print out line then return back to previous position.
if(fgetc(ifp)=='\n') {
getline(&line, &len, ifp);
printf("%s", line);
fseek(ifp,-strlen(line), SEEK_CUR);
line_count++;
//free(line);
} else {
//move back a single positon
fseek(ifp,-(strlen(line)+2), SEEK_CUR);
}
}
//free(line);
fclose(ifp);
printf("-----\nfunction exited\n-------\n");
}
答案 0 :(得分:0)
你可以:
将最后N行保留在缓冲区中并继续前进,或
从文件末尾开始,向后移动N行。
考虑到任意文件大小,第二种方法更有效。所以你的方法很好而且效率更高。 但是,您的代码需要工作。
在您的代码中,您可能需要检查文件中的行数少于k
的情况。请查看GNU here中的尾部实现以获取更多信息。
1)内存泄漏:需要在最后释放分配了getline的内存:
if(line)
free(line)
2)当您点击'\n'
时(您的if
变为true
),您仍然应该先退后(想想文件中最后'\n'
会发生什么,那是你希望击中的第一个'\n'
。但是,您的代码执行的是getline
。
3)您的else
不会寻找单个位置,它取决于之前strlen(line)
的值而不是当前行,并且您可能会错过这个搜索所需的'\n'
或你的寻求可能是非法的 - >确保你不会在向后的时候点击文件的开头。