我正在阅读stringstream
的实例。在从流中获取数据的某个点上,我需要读取可能存在或不存在的标识符。逻辑是这样的:
std::string identifier;
sstr >> identifier;
if( identifier == "SomeKeyword" )
//process the the rest of the string stream using method 1
else
// back up to before we tried to read "identifier" and process the stream using method 2
我如何实现上述逻辑?
答案 0 :(得分:5)
std::string identifier;
std::stringstream::pos_type pos = sstr.tellg();
sstr >> identifier;
if (identifier == "SomeKeyword")
{
//process the rest of the string stream using method 1
}
else
{
// back up to before we tried to read "identifier
sstr.seekg(pos);
// process the stream using method 2
}
答案 1 :(得分:3)
您可以在获取标识符之前获取流中的get指针,并在标识符错误时恢复位置:
std::string identifier;
std::stringstream::pos_type pos = sstr.tellg();
sstr >> identifier;
if( identifier == "SomeKeyword") {
// process the the rest of the string stream using method 1
} else {
sstr.clear();
sstr.seekg(pos, sstr.beg);
// process the stream using method 2
}
page on tellg
at cplusplus.com有一个非常好的例子。调用clear()
的目的是确保seekg
即使先前的读取到达文件结尾也能正常工作。这仅适用于C ++ 11之前的C ++版本。如果您使用的是C ++ 11或更高版本,seekg
会自动清除EOF位,并且不应在解决方案中包含clear()
行。感谢@metal指出这一点。
答案 2 :(得分:2)
您可以直接查看stringstream
的内容。这可能是一个比提取和回滚更清晰的方法,因为在提取后你不能保证stringstream
的条件。例如,如果您的字符串只包含一个单词,则提取它会设置ios_base::iostate::eofbit
标记。
您可以完成检查stringstream
的内容,如下所示:
if(sstr.str().compare(0, identifier.length(), identifier) == 0) {
sstr.ignore(identifier.length());
// process the the rest of the string stream using method 1
} else {
// process the stream using method 2
}
如果您依赖于stringstream
的提取运算符来消除领先的空格,那么您需要在执行compare
之前进行清除。这可以在if
- 块之前使用命令sstr >> skipws;
完成。
虽然我确实认为这种方法更安全,但应该注意的是,如果你依赖于sstr
中的前导空格,那么方法2"那么你应该使用其中一个答案(但是你也应该重新考虑你对stringstream
的使用,因为所有的提取操作员都先吃掉空格。)