为什么写空 std::istringstream.rdbuf() 会设置 failbit?
Why does writing empty std::istringstream.rdbuf() set failbit?
我了解到,我可以通过输出 istream 的 rdbuf() 将 C++ std::istream 复制到 C++ std::ostream。我用了好几次,效果很好。
今天我遇到了麻烦,因为这个操作设置了 badbit,如果 std::istream 是空的(至少对于 std::istringstream)。我编写了以下代码来演示我的问题:
#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=%d\n", ss.fail());
ss << std::istringstream("").rdbuf(); // why does this set failbit ???
printf("fail=%d\n", ss.fail());
}
我尝试了 Windows/VS2017 和 Linux/gcc-9.20,两者的行为相同。
我在默认值为 std::istringstream("") 的方法签名中使用 std::istream&。调用代码应该能够传递一个可选的 istream,它附加到一些其他数据。
- 谁能解释一下,为什么要设置 badbit?
- 有没有更好的方法来实现这个可选的 std::istream& 参数?
我知道,我可以编写两种方法,一种带有额外的 std::istream& 参数,但我想避免重复代码。
提前致谢,
马里奥
20 年 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=%d\n", out.fail());
}
我还添加了有关在将空文件复制到
时设置 failbit 的警告
ostream::operator<<
的文档描述了读取流的以下行为:
Behaves as an UnformattedOutputFunction. After constructing and checking the sentry object, checks if sb is a null pointer. If it is, executes setstate(badbit)
and exits. Otherwise, extracts characters from the input sequence controlled by sb and inserts them into *this
until one of the following conditions are met:
* 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).
If no characters were inserted, executes setstate(failbit)
. If an exception was thrown while extracting, sets failbit and, if failbit is set in exceptions(), rethrows the exception.
如您所知,这明确表示尝试插入空缓冲区将设置 failbit
。如果你想让它成为“可选”,只需在插入缓冲区之前检查流是否良好,然后执行 ss.clear()
以清除故障位。
我了解到,我可以通过输出 istream 的 rdbuf() 将 C++ std::istream 复制到 C++ std::ostream。我用了好几次,效果很好。
今天我遇到了麻烦,因为这个操作设置了 badbit,如果 std::istream 是空的(至少对于 std::istringstream)。我编写了以下代码来演示我的问题:
#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=%d\n", ss.fail());
ss << std::istringstream("").rdbuf(); // why does this set failbit ???
printf("fail=%d\n", ss.fail());
}
我尝试了 Windows/VS2017 和 Linux/gcc-9.20,两者的行为相同。
我在默认值为 std::istringstream("") 的方法签名中使用 std::istream&。调用代码应该能够传递一个可选的 istream,它附加到一些其他数据。
- 谁能解释一下,为什么要设置 badbit?
- 有没有更好的方法来实现这个可选的 std::istream& 参数?
我知道,我可以编写两种方法,一种带有额外的 std::istream& 参数,但我想避免重复代码。
提前致谢,
马里奥
20 年 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=%d\n", out.fail());
}
我还添加了有关在将空文件复制到
时设置 failbit 的警告ostream::operator<<
的文档描述了读取流的以下行为:
Behaves as an UnformattedOutputFunction. After constructing and checking the sentry object, checks if sb is a null pointer. If it is, executes
setstate(badbit)
and exits. Otherwise, extracts characters from the input sequence controlled by sb and inserts them into*this
until one of the following conditions are met:* 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).
If no characters were inserted, executes
setstate(failbit)
. If an exception was thrown while extracting, sets failbit and, if failbit is set in exceptions(), rethrows the exception.
如您所知,这明确表示尝试插入空缓冲区将设置 failbit
。如果你想让它成为“可选”,只需在插入缓冲区之前检查流是否良好,然后执行 ss.clear()
以清除故障位。