7

一致をイテレータに割り当てるCのsscanfを置き換える関数をC++で記述したいと思います。

基本的に、私は次のようなものが欲しいです:

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]);

正確な詳細は異なる場合がありますが、あなたはその考えを理解します。実装のアイデアはありますか?

これまでのオプションとこれまでの問題:

  • std :: istringstream:定数式を照合するためのマニピュレーターはありません
  • Boost.Regex:これが機能するかどうかわからないため、これに必要なものよりもはるかに複雑に見える
  • Boost.Spirit:これが動的に生成されたフォーマット文字列に対して機能するとは思わない。また、必要以上に複雑に見える
  • sscanf:動作しますが、非標準などであり、引数の数はコンパイル時に決定されるため、これを使用すると多くのオーバーヘッドが必要になります。
4

2 に答える 2

2

それについてはどうですか?

void sscanf(std::string str,
            const std::string& format,
            std::vector<boost::any>& result)
{
  std::string::const_iterator i = format.begin();
  while (i != format.end())
  {
    if (*i == '%')
    {
      ++i; // now *i is the conversion specifier
      char specifier = *i;

      ++i; // now *i is the next seperator
      std::string extract = str.substr(0, str.find(*i));

      switch (specifier) 
      {
        // matching an integer
        case 'i':
          result.push_back(boost::lexical_cast<int>(extract));
          break;
        // matching a floating point number
        case 'a': case 'e': case 'f': case 'g':
          result.push_back(boost::lexical_cast<float>(extract));
          break;
        // matching a single character
        case 'c':
          result.push_back(boost::lexical_cast<char>(extract));
          break;
        // matching a string
        case 's':
          result.push_back(extract);
          break;
        // Invalid conversion specifier, throwing an exception
        default:
          throw std::runtime_error("invalid conversion specifier");
          break;
      }
    }
    else
    {
      // if it's not a %, eat!
      str.erase(0, str.find(*i)+1);
      ++i;
    }
  }
}

一部の変換指定子が欠落していますが、基本的には機能します。

于 2011-02-18T16:07:30.023 に答える
2

フォーマット文字列がコンパイル時に決定される場合、いくつかの可変長テンプレートの printf置換が書き込まれます。それらを反転すると、かなりうまくいくはずです。

次に、読み取りに istream の >> 演算子、または c-stdlib 関数を使用できます。

于 2011-02-17T23:26:07.730 に答える