为什么parse_config_file流上设置故障位



这个最小的程序使用boost::program_options来解析stringstream。奇怪的是,解析后,流不再处于"良好"状态,并且设置了failbit和eofbit。

#include <iostream>
#include <sstream>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>
void test_stream(std::stringstream& s);
int main()
{
  using namespace std;
  namespace po = boost::program_options;
  stringstream s;
  s << "seed=3" << 'n';
  test_stream(s);
  po::options_description desc("");
  desc.add_options()
    ("seed", po::value<int>());
  po::variables_map vm;
  po::store(po::parse_config_file(s, desc, true), vm);
  po::notify(vm);
  test_stream(s);
  return 0;
}
void test_stream(std::stringstream& s)
{
  using namespace std;
  if (s.good())
    {
      cout << "stream is good" << endl;
    }
  else
    {
      cout << "stream is not good" << endl;
      if (s.rdstate() & ios_base::badbit)
    cout << "badbit is set" << endl;
      if (s.rdstate() & ios_base::failbit)
    cout << "failbit is set" << endl;
      if (s.rdstate() & ios_base::eofbit)
    cout << "eofbit is set" << endl;
    }
}

输出:

stream is good
stream is not good
failbit is set
eofbit is set

尽管以某种方式预期了 eof 条件,因为大概解析器已经读取了流直到 EOF,为什么还要设置故障位?

根据 ios::eof 标志的文档,在某些情况下可能会发生这种情况:

尝试在文件末尾读取的操作失败,因此最终设置了 eofbit 和 failbit。此函数可用于检查失败是由于到达文件末尾还是由于某些其他原因。

Boost 的解析器使用流上的std::copy()和迭代器来提取选项。正如Jerry Coffin对另一个问题的回答中所指出的,迭代器从序列中读取项目。读取最后一个后,序列的eof位被设置。当迭代器再次递增以获得流结束迭代器时,这是将循环留在copy()中的条件,它尝试再次读取,因此也设置了流的fail位。

最新更新