[英]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.