C++ - 如果自定义提取器失败,如何恢复 istream
C++ - How to recover istream if self defined extractor fails
我需要一个自定义提取器(运算符>>(来读取特定字符串到我自己的数据类型中。
问题是对字符串的要求很大。
因此,最简单的方法可能是从 istream 中读取整个字符串,然后检查是否满足所有要求。
我的问题是字符串是否无效。据我所知,C++流保持不变是很常见的。
在这种情况下,恢复 istream 的最佳实践是什么?以下示例中的异常处理是否足够?
std::istream& operator>>(std::istream& is, Foo& f)
{
std::string str;
if (is >> str)
{
// check if string is valid
if ( is_valid( str ) )
{
// set new values in f
}
else
{
// recover stream
std::for_each(str.rbegin(), str.rend(),
[&] (char c)
{
is.putback(c);
});
// ste failbit
is.clear(std::ios_base::failbit);
}
}
return is;
}
那么 std::getline(( 而不是>> str 呢?还有其他陷阱吗?
谢谢
马可
您无法将流恢复到开始阅读的初始位置,至少在一般情况下是这样。理论上,您可以放回字符或查找到以前去过的位置,但许多流缓冲区不支持放回字符或查找。标准库提供了一些有限的指导,但它处理的是相当简单的类型,例如整数:只要格式匹配并且它就在那里停止,字符就会被读取。即使格式匹配,也可能存在一些可以更早检测到的错误。
下面是一个演示标准库行为的测试程序:
#include <iostream>
#include <sstream>
void test(std::string const& input)
{
std::istringstream in(input);
int i;
std::string tail;
bool result(in >> i);
in.clear();
std::getline(in, tail);
std::cout << "input='" << input << "' "
<< "fail=" << std::boolalpha << result << " "
<< "tail='" << tail << "'n";
}
int main()
{
test("10 y");
test("-x y");
test("0123456789 x");
test("123456789012345678901234567890 x");
}
只是为了解释四个测试用例:
- 只是为了确保测试执行它应该做的事情,第一个输入实际上是可以的,没有问题。
- 第二个输入以与格式匹配的字符开头,后跟不匹配的内容,读取在
'-'
字符之后立即停止。 - 第三个测试使用八进制数字读取
int
。可能在字符'8'
上检测到故障,但'8'
和'9'
都会消耗,输入也会失败。
最后一个示例会导致溢出,可以在读取所有数字 - 之前检测到溢出,但仍会读取所有数字。
基于此,我认为当对格式正确的输入进行语义检查失败时,不会期望将流重置到原始位置。
相关文章:
- 用C++将哈希表写入文件并从文件中恢复
- Opencv 恢复到比我设置的更高的分辨率
- 变量在使用赋值语句赋值后恢复为以前的值
- 在信号处理程序中捕获C++未处理的异常并恢复应用程序
- 删除所有字符串后如何恢复 QStringList?
- 当对套接字 send() 的同步调用由于连接另一端丢失而被阻止时,如何恢复?
- 如何仅使用一次固定<<设置精度(2)?或者至少恢复到默认行为?
- "co_yield"是否可以在恢复协程时从调用方返回值?
- OpenSSL C API:如何在程序exec()之后恢复TLS连接?
- 通过指针恢复对数组的引用.UB与否?
- 从不同进程中的另一个线程挂起/恢复线程或进程
- 如何在 XML 中正确存储原始字节数据并恢复它?
- ExtTextOut 文本的持续闪烁,在一段时间后,文本将恢复为默认字体
- 模板化类中运算符 + 重载的值的恢复
- C++ 线程创建/删除与线程停止/恢复
- ZMQ::send() 抛出异常并终止 QNX 进程.为什么以及如何从中恢复?
- Windows桌面程序保存您的计算机会话 - 基于程序崩溃时的恢复会话
- xSemaphoreTake 在调用 xSemaphoreGive 后不会恢复任务
- 将类型映射到整数值后,如何在给定整数值的情况下恢复类型?
- 恢复ASIO无堆栈Coroutine