C++/Boost:编写更强大的sscanf替代品

deu*_*ger 7 c++ boost boost-spirit boost-regex boost-spirit-qi

我想用C++编写一个函数来替换C的sscanf,它将匹配分配给迭代器.

基本上,我想要的东西:

string s = "0.5 6 hello";
std::vector<boost::any> any_vector;
sscanv(s, "%f %i %s", any_vector);
cout << "float: " << any_cast<float>(any_vector[0]);
cout << "integer: " << any_cast<integer(any_vector[1]);
cout << "string: " << any_cast<string>(any_vector[2]);
Run Code Online (Sandbox Code Playgroud)

确切的细节可能会有所不同,但你明白了.任何实施的想法?

到目前为止的选项以及目前的问题:

  • std :: istringstream:没有用于匹配常量表达式的操纵器
  • Boost.Regex:不确定这是否有效,而且看起来要比这更复杂
  • Boost.Spirit:不要认为这适用于动态生成的格式字符串,并且它似乎也更复杂
  • sscanf:它可以工作,但是非标准等,并且使用它会需要很多开销,因为参数的数量是在编译时确定的

Kar*_*oor 2

那是怎么回事?

\n\n
void sscanf(std::string str,\n            const std::string& format,\n            std::vector<boost::any>& result)\n{\n  std::string::const_iterator i = format.begin();\n  while (i != format.end())\n  {\n    if (*i == \'%\')\n    {\n      ++i; // now *i is the conversion specifier\n      char specifier = *i;\n\n      ++i; // now *i is the next seperator\n      std::string extract = str.substr(0, str.find(*i));\n\n      switch (specifier) \n      {\n        // matching an integer\n        case \'i\':\n          result.push_back(boost::lexical_cast<int>(extract));\n          break;\n        // matching a floating point number\n        case \'a\': case \'e\': case \'f\': case \'g\':\n          result.push_back(boost::lexical_cast<float>(extract));\n          break;\n        // matching a single character\n        case \'c\':\n          result.push_back(boost::lexical_cast<char>(extract));\n          break;\n        // matching a string\n        case \'s\':\n          result.push_back(extract);\n          break;\n        // Invalid conversion specifier, throwing an exception\n        default:\n          throw std::runtime_error("invalid conversion specifier");\n          break;\n      }\n    }\n    else\n    {\n      // if it\'s not a %, eat!\n      str.erase(0, str.find(*i)+1);\n      ++i;\n    }\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

某些转换说明符缺少 \xe2\x80\x93 但基本上它可以工作。

\n