【发布时间】:2019-12-20 19:18:48
【问题描述】:
请帮助我了解以下程序行为不同的原因。
程序从一个源和一个过滤器创建一个测试文本文件和一串增强过滤器 (filtering_istream)。然后它会尝试读取一些行。
#include <iostream>
#include <fstream>
#include <string>
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/filtering_stream.hpp>
class my_filter : public boost::iostreams::input_filter
{
public:
explicit my_filter(std::ostream& s) : m_out(s)
{}
template<typename Source>
int get(Source& src)
{
int c = boost::iostreams::get(src);
if(c == EOF || c == boost::iostreams::WOULD_BLOCK)
return c;
if(c == '\r')
return boost::iostreams::WOULD_BLOCK;
if(c == '\n')
{
m_out << m_str << std::endl;
m_str = "";
}
else
{
m_str += c;
}
return c;
}
private:
std::ostream& m_out;
std::string m_str;
};
int main()
{
using namespace std;
boost::iostreams::filtering_istream file;
const std::string fname = "test.txt";
std::ofstream f(fname, ios::out);
f << "Hello\r\n";
f << "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111\r\n";
f << "World!\r\n";
f.close();
file.push(my_filter(std::cout));
file.push(boost::iostreams::file_descriptor(fname));
std::string s;
while(std::getline(file, s))
{}
return 0;
}
用clang在线编译显示预期结果:
但如果我将字符串“111...111”(128 个)更改为 127 个(255 等),结果会有所不同:
我觉得这种行为不正确。
注意:“111...111”(127 个)的长度与boost::iostreams::filtering_istream::push 方法中的default buffer_size 相关。 ..
file.push(my_filter(std::cout), default_buf_size=...)
您可以在这里查看和运行代码:code_example
更新 1
奇怪的是,在某些情况下,WOULD_BLOCK 的返回值可以让你进一步阅读,而在其他情况下,它认为文件已完成。但根据文档:
WOULD_BLOCK - 表示输入暂时不可用
所以它并不表示流的结束。
【问题讨论】:
-
不确定它将如何影响您的代码,但您是否尝试过使用二进制形式 (
ios::binary) 而不是文本形式写入文件?在 Windowsstd::ofstream下,在文本模式下操作时,已将“\n”替换为“\r\n”。因此,您的文件中的 '\r' 字符可能比您预期的要多。在线编译器通常在下面使用 linux,其中没有前面的 '\r' 的唯一 '\n' 应该作为行尾,而文本模式下的std::ofstream不会在文件中添加任何额外的 '\r'。
标签: c++ c++11 boost iostream boost-iostreams