为什么写空std::istringstream.rdbuf()会设置失败位



我已经学会了,我可以通过输出istreams的rdbuf((将C++std::istream复制到C++std::ostream。我用了好几次,效果很好。

今天我遇到了麻烦,因为如果std::istream为空(至少对于std::distingstream(,此操作会设置badbit。我写了以下代码来演示我的问题:

#include <stdio.h>
#include <sstream>
int main(int argc, char *argv[])
{
std::ostringstream ss;
ss << std::istringstream(" ").rdbuf(); // this does not set failbit
printf("fail=%dn", ss.fail());
ss << std::istringstream("").rdbuf(); // why does this set failbit ???
printf("fail=%dn", ss.fail());
}

我尝试了Windows/VS2017和Linux/gcc-9.20,它们的行为都是一样的。

我正在使用std::istream&默认值为std::istringstream("(的方法签名中。调用代码应能够传递一个可选的istream,该istream附加到一些其他数据中。

  • 有人能解释为什么设置了坏比特吗
  • 有没有更好的方法来实现这个可选的std::istream&参数

我知道,我可以写两个方法,一个带有额外的std::istream&参数,但我想避免重复代码。

提前感谢

马里奥

更新日期:2020年4月22日

我现在使用以下代码:

#include <stdio.h>
#include <sstream>
int main(int argc, char *argv[])
{
std::ostringstream out;
std::istringstream in("");
while (in)
{
char Buffer[4096];
in.read(Buffer, sizeof(Buffer));
out.write(Buffer, in.gcount());
}
printf("fail=%dn", out.fail());
}

我还添加了一个关于在将空文件复制到时设置故障位的警告https://stackoverflow.com/a/10195497/6832488

ostream::operator<<的文档描述了读取流的以下行为:

表现为未格式化的输出函数。在构造并检查哨兵对象之后,检查某人是否为空指针。如果是,则执行setstate(badbit)并退出。否则,从sb控制的输入序列中提取字符,并将其插入*this,直到满足以下条件之一:

* end-of-file occurs on the input sequence;
* inserting in the output sequence fails (in which case the character to be inserted is not extracted);
* an exception occurs (in which case the exception is caught). 

如果未插入任何字符,则执行setstate(failbit)。如果在提取时引发异常,则设置故障位,如果在exceptions((中设置了故障位,则重新引发异常。

正如您所知,它明确表示尝试插入空缓冲区将设置failbit。如果你想从本质上做到";可选";,只需在插入缓冲区之前检查流是否良好,然后执行ss.clear()以清除故障位。

最新更新