有没有办法检查正在读取的文件行是否是文件中的最后一行?

时间:2016-01-31 14:52:00

标签: c

我想要一种方法来检查何时读取文件的最后一行。有没有办法可以做到这一点?

4 个答案:

答案 0 :(得分:5)

是。尝试读另一行。如果这会产生文件结束条件,那么您之前读过的行就是最后一行。有些方法可能会在不尝试阅读另一条线的情况下获得类似结果,但它们只能在特定条件下工作并且容易出现竞争条件。

如果这太复杂,可以考虑在用于读取缓冲一行的行的函数周围编写一个包装器。然后,这个包装器可以通过检查它是否能够提前读取另一行来假装知道它到达文件末尾。

答案 1 :(得分:2)

不,没有一般方法可以知道正在读取的行是否是文件的最后一行。

原因是行号仅由文件中的数据确定。在您阅读了数据的相关部分并检查其是否存在行尾标记之前,无法知道您的阅读器在哪一行。

当您可以告诉行号甚至导航到特定行时,两种特殊情况是文件中的所有行如下所示:

  • 所有行都有预定的固定长度 - 在这种情况下,可以将文件中的位置与文件的大小进行比较,以确定这是否是最后一行
  • 该文件包含"标题"所有行的索引 - 在这种情况下,您可以执行添加,并通过分析索引来确定定位。

答案 2 :(得分:1)

判断刚读取的行是否是文件中的最后一行的方法...

FILE *fp = fopen( filename, "r" );
fseek( fp, 0, SEEK_END );
long filesize = ftell( fd );
fseek( fp, 0, SEEK_SET);

....

fgets( buffer, sizeof buffer, fp);
if (filesize == ftell(fp) )
{
    // then last line is read
}

当然,需要在每个系统函数调用中执行适当的错误检查;但是,上面的内容将让代码知道何时读取最后一行。

注意:上述方法不适用于管道,fifos以及访问外部总线时。

答案 3 :(得分:0)

如果可以查找文件,那么如果您知道该文件的最大行长度,则可以使用fseek来执行此操作。

ssize_t len;
char buf[max_len + 1];
//remember current position before fseek
currp = ftell(fd);

// set the file pointer to the beginning of the last line
fseek(fd, -max_len, SEEK_END);

// compare current position
if (ftell(fd) <= currp)
{
    // this might be the last line
    // now we have to check if there is only single '\n'

    // read file block
    len = read(fd, buf, max_len);
    if (len == -1)
    {
        perror("read failed");
        return -1;
    }
    buf[len] = '\0';
    if (strchr(buf, '\n') == strrchr(buf, '\n'))
    {
        // single newline was found
        // it is the last line
        // revert the pointer changes
        fseek(fd, currp, SEEK_SET);
        return 0;
    }
}

你必须意识到竞争条件的可能性。