gpt4 book ai didi

C++ 流提取运算符重载

转载 作者:搜寻专家 更新时间:2023-10-31 01:39:49 25 4
gpt4 key购买 nike

这是一个关于用户编写的 C++ 输入流提取运算符 (>>) 的哲学(规范设计)的问题。

假设在进入 >> 运算符实现(对于用户编写的类)时,已经为输入流设置了 eof 标志。

应该是用户编写的提取运算符(>>)

  1. 设置失败标志(因为找不到所需对象的实例)
  2. 它是否应该在 eof 标志仍然设置的情况下返回给调用者。

如果使用第二种方法,则意味着调用者必须始终在尝试调用 >> 运算符之前检查 eof 标志。原因是 >> 运算符可能会成功提取所需类的实例并设置 eof 标志。

原始代码如下。根据下面的评论,这段代码似乎是错误的。如果 eof 已经在输入上设置,提取运算符将简单地返回 eof 仍然设置。似乎如果设置了 eof,但未设置 bad 和 fail,则应提取字符串以设置失败位。当然也可以直接设置fail位。

/* Implement the C/C++ >> (stream input) operator as a non-member 
function */
std::istream &operator>>(std::istream& is, DecNumber &val) {
DecContext context{DecContext::defInit};
uint32_t status;
/* The true value below prevents whitespace from being skipped */
std::istream::sentry s(is, true);
std::string inStr;
/* Check if the input stream is in a good state. Just return to the
caller if the input stremm is not in a good state. The caller
must handle this condition. */
if(!s)
return is;
/* Get a string from the input stream. This string is converted to
a DecNumber below. Just return to the caller if this step causes
any stream related errors. Note that reaching the end of the
input is not a stream related error here. A decimal number might
be the absolute last thing in the stream. */
is >> inStr;
if (is.bad() || is.fail())
return is;
/* Try to convert the string to a DecNumber using the default context
value */
decNumberFromString(val.getDecVal(), inStr.c_str(), context.getDecCont());
status = context.DecContextGetStatus();
/* Remove a few status bits we don't care about */
status &= ~(DEC_Inexact + DEC_Rounded);
if (status)
is.setstate(std::ios_base::failbit);
return is;
}

最佳答案

您应该实现解决方案 1。

如有疑问,只需看看已经完成的工作即可。正如您在下面看到的,如果我们尝试从 EOF 状态的流中读取,则会设置失败位。

请注意,EOF 并不是失败的唯一方法。尝试在下面的代码中设置 std::string vals = "52 43 A";

failbit 如果出于任何原因operator>> 实际上并未流式传输值,则应设置它。 EOF 只是其中一个原因。

#include <sstream>
#include <iostream>
#include <string>

void print_stream (std::istream & print_me, int const & i)
{
std::cout << "i: " << i << "\n";
std::ios_base::iostate bits = print_me.rdstate();

std::cout << "good: " << (bits & std::ios_base::goodbit) <<
", bad: " << (bits & std::ios_base::badbit) <<
", fail: " << (bits & std::ios_base::failbit) <<
", eof: " << (bits & std::ios_base::eofbit) << "\n";

std::cout << "\n----------------------------\n\n";
}

int main (void)
{
std::string vals = "52 43";
std::istringstream iss(vals);
int i;

iss >> i;
print_stream (iss, i);
iss >> i;
print_stream (iss, i);
iss >> i;
print_stream (iss, i);
iss >> i;
print_stream (iss, i);

return 0;
}

输出

$ ./a.exe
i: 52
good: 0, bad: 0, fail: 0, eof: 0

----------------------------

i: 43
good: 0, bad: 0, fail: 0, eof: 2

----------------------------

i: 43
good: 0, bad: 0, fail: 4, eof: 2

----------------------------

i: 43
good: 0, bad: 0, fail: 4, eof: 2

----------------------------

请注意,典型的读取模式循环是...的一些变体

while (input >> var >> var2 >> var3)
{
// failbit is not set. All reads succeeded.
// Do Stuff
}

如果您需要检测在读取多个值期间是否在某个时刻发生了故障,那么是的,您需要更复杂一点并进行一些测试,例如...

while (true)
{
if (input >> var)
{
// We successfully read first value
if (input >> var2 >> var3)
{
// We succesfully read all the values!
// Do stuff
}
else
{
ErrorLog ("Partial line read!");
break;
}
else
{
// Nothing else to read
break;
}
}

关于C++ 流提取运算符重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30628107/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com