我正在编写一个自定义的>>
运算符,该运算符逐字符读取整个流字符并用每个字符更新对象,如下所示:
class MyClass
{
public:
bool Process(char c);
}
std::istream& operator>>(std::istream& input, MyClass& value)
{
if (input)
{
char c;
bool parsing_success = true;
while (parsing_success && input >> c)
{
parsing_success = value.Process(c)
}
if (!parsing_success)
input.setstate(std::ios_base::failbit);
}
return input;
}
想法是逐个字符地读取流,直到到达流的末尾或遇到MyClass
不喜欢的字符为止。当后者发生时,操作员将引发错误。
我打算像这样使用它:
MyClass value;
if (std::cin >> value)
{
//do something with value
}
else
{
//handle error
}
我遇到的问题是,在读取整个流后,istream::fail()
返回true,因为到达了流的末尾,这同时设置了eof
和fail
(如[C0等其他问题中所示])。
因此,即使成功处理了流,this也会返回false。
[现在,运算符的调用者可能会检查std::cin >> value
位是否已设置,但是我觉得这不是eof
运算符的其他标准用法模式所惯用的-例如>>
。
所以我的问题是-成功处理流后,我应该调用istream :: clear吗?。像这样的东西:
int x; if (cin >> x) { //do something }
这将清除故障位,并确保if (!parsing_success)
input.setstate(std::ios_base::failbit);
else
input.clear();
仅在存在合法流错误或遇到无效字符时才返回false。但是,我不确定这是否是惯用的C ++或会导致其他问题。
谢谢!
我应该在成功处理完 流?
这很好,因为您的流成功读取了整个输入,而这正是用户定义的std::cin >> value
应该执行的操作,因此它应该报告成功。我将其更改为清除istream::clear
之外的掩码,因为这是用户可以使用的额外信息,并且不会影响if语句:
operator>>()