struct T
{
void eat(std::string const& segment)
{
buffer << segment;
std::string sentence;
while (std::getline(buffer, sentence))
std::cout << "[" << sentence.size() << "]";
}
std::stringstream buffer;
};
int main() {
T t;
t.eat("A\r\nB\nC\nD");
// ^^ ^ ^ ^
}
// Actual output: [2][1][1][1]
// Desired output: [1][1][1][1]
我希望std::stringstream
为我取消回车(并且不希望复制和修改segment
)。
我怎么能这样做?我本以为无论如何,这会发生在Linux上,对于文本模式的流......但也许这种机制是在 file 流的逻辑中。
答案 0 :(得分:2)
在读取创建的文件时,这是Unix机器上的一般问题 一台Windows机器。我建议在输入端进行清理 水平。
我在阅读基于行的文件时发现的最佳解决方案之一是 创建一个类似于:
的类class Line
{
std::string myText;
public:
friend std::istream& operator>>( std::istream& source, Line& dest )
{
std::getline( source, dest.myText );
if ( source ) {
dest.myText.erase(
std::remove( dest.myText.begin(), dest.myText.end(), '\015' ),
dest.myText.end() );
}
return source;
}
operator std::string() const
{
return myText;
}
};
您可以根据需要添加其他功能:自动类型转换
例如,在尝试匹配模板时没有播放,我发现了它
用于添加朋友以包裹boost::regex_match
。
我使用此功能(没有'\015'
删除),即使我不必这样做
担心Windows / Linux差异;它支持使用阅读线
例如std::istream_iterator<Line>
。
另一个解决方案是使用插入的过滤streambuf 输入流。这也很简单:
class RemoveCRStreambuf : public std::streambuf
{
std::streambuf* mySource;
char myBuffer; // One char buffer required for input.
protected:
int underflow()
{
int results = mySource->sbumpc();
while ( results == '\015' ) {
results = mySource->sbumpc();
}
if ( results != EOF ) {
myBuffer = results;
setg( &myBuffer, &myBuffer + 1, &myBuffer + 1 );
}
return results;
}
public:
RemoveCRStreambuf( std::streambuf* source )
: mySource( source )
{
}
};
要插入它:
std::streambuf* originalSB = source->rdbuf();
RemoveCRStreambuf newSB( originalSB );
source->rdbuf( &newSB );
// Do input here...
source->rdbuf( originalSB ); // Restore...
(显然,使用某种RAII进行修复将是
优选的。我自己的过滤streambuf有一个构造函数
std::istream
;他们也保存了一个指针,并恢复
streambuf在他们的析构函数中。)