std :: getline和eol vs eof

时间:2009-08-05 20:04:12

标签: c++ file-io

我有一个正在追踪不断增长的文件的程序。

我试图避免从文件中抓取部分行(例如,在行完全由其他进程写入之前读取。)我知道它在我的代码中发生,所以我试图专门捕获它。 / p>

有没有理智的方法来做到这一点?

以下是我正在尝试的内容:

if (getline (stream, logbuffer))
{
    if (stream.eof())
    {
        cout << "Partial line found!" << endl;
        return false;
    }
    return true;
}
return false;

但是,我不能轻易地重现问题所以我不确定我是否正在使用此代码检测它。 std :: getline剥离换行符,因此我无法检查缓冲区是否有尾随换行符。我的日志消息(上图)永远不会跳闸。

是否还有其他方法可以检查我想要检测的内容?有没有办法知道我读到的最后一行是否在没有找到EOL字符的情况下点击了EOF?

感谢。

4 个答案:

答案 0 :(得分:3)

这永远不会成真:

if (getline (stream, logbuffer))
{
    if (stream.eof())
    {
       /// will never get here

如果getline()有效,则流不能处于eof状态。 eof()和相关状态测试仅适用于先前读取操作的结果,例如getline() - 它们不会预测下一次读取将执行的操作。

据我所知,没有办法做你想做的事。但是,如果其他进程一次写入一行,那么您所说的问题应该非常罕见(根据我的经验不存在),具体取决于您正在使用的操作系统。我怀疑问题出在其他地方,可能在你的代码中。拖尾文件是一件非常常见的事情,通常不需要使用特殊代码来执行此操作。

但是,如果您发现需要读取部分线,基本算法如下:

forever do
   wait for file change
   read all possible input using read or readsome (not getline)
   chop input into lines and possible partial line
   process as required
end

答案 1 :(得分:1)

istream这样的std::cin对象有一个get function,当它到达换行符时会停止读取而不从流中提取它。然后,您可以peek()get()查看它是否确实是换行符。问题是您必须知道来自其他应用程序的行的最大长度。示例(未经测试)代码如下:

char buf[81];  // assumes an 80-char line length + null char
memset(buf, 0, 81);

if (cin.get(buf, 81))
{
    if (cin.peek() == EOF)  // You ran out of data before hitting end of line
    {
        cout << "Partial line found!\n";
    }
}

答案 2 :(得分:0)

即使其他程序没有完成写入文件,在行结束的文件中,除了等待查看其他程序是否写入新内容之外,没有办法区分其他程序。

编辑:如果您只是想知道该行是否以换行符结尾,您可以编写自己的getline函数,该函数读取直到它到达换行符但不删除它。 / p>

答案 3 :(得分:0)

我不得不对你在这里发表的一个声明提出异议:

  

但是,我不能轻易地重现这个问题所以我不确定我是否正在使用此代码检测它。

似乎从你所说的那里复制你的问题非常容易,如果你说的话。您可以在某个文本编辑器中轻松创建文本文件 - 只需确保最后一个像EOF结束而不是转到新行。然后将程序指向该文件并查看结果。