繁体   English   中英

std :: getline和eol与eof

[英]std::getline and eol vs eof

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

我试图避免从文件中抓取部分行(例如,在其他进程完全写完该行之前先进行读取。)我知道它正在我的代码中发生,因此我试图专门捕获它。

有理智的方法吗?

这是我正在尝试的:

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

但是,我无法轻松重现该问题,因此不确定使用此代码检测到它。 std :: getline去除换行符,因此我无法检查缓冲区中是否包含尾随的换行符。 我的日志消息(以上)从未触发。

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

谢谢。

这将永远是不正确的:

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

如果getline()有效,则流不能处于eof状态。 eof()和相关的状态测试仅对诸如getline()之类的上一个读取操作的结果起作用-它们不预测下一个读取将做什么。

据我所知,没有办法做你想做的事。 但是,如果其他进程一次写一行,那么您所说的问题应该很少见(我的经验中不存在),在某种程度上取决于您所使用的OS。 我怀疑问题出在其他地方,可能在您的代码中。 尾随一个文件是很常见的事情,通常不需要使用特殊代码来完成它。

但是,如果发现确实需要读取部分行,则基本算法如下:

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

istream对象(例如std::cin具有get函数 ,该函数在到达换行符时会停止读取,而不会从流中提取它。 然后,您可以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";
    }
}

即使其他程序没有写完文件,也就是该行结束处的文件,所以除了等待其他程序是否写新东西外,别无其他方法。

编辑:如果只想知道行是否以换行符结尾,则可以编写自己的getline函数,该函数读取直到碰到换行符但不会剥离它。

我必须对您在这里发表的一项声明表示怀疑:

但是,我无法轻松重现该问题,因此不确定使用此代码检测到它。

从您所说的看来,如果确实如此,那么复制您的问题将非常容易。 您可以在某些文本编辑器中轻松创建文本文件-只需确保最后一个like以EOF结尾,而不是继续换行。 然后将程序指向该文件并查看结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM