2013-10-28 11 views
6

私は、設定ファイルやテキストベースのプロトコル(人間ではなく機械で書かれたもの)から整数を解析するために使用できるヘルパー関数を書こうとしています。私はHow to parse a string to an int in C++?を読んだが、そこの解決策はすべての問題に対処していない。私は、(最も重要度の低いものから最も重要度の低いものを)希望します。C++での整数の強力な解析

  1. 範囲外の値を拒否します。 strtoulとstrtoullはこれを達成していません。負の符号がある場合、値は "戻り値の型"で否定されます。したがって、 "-5"は幸いに解析され、エラーを通知する代わりに4294967291または18446744073709551611を返します。
  2. グローバルロケールの設定に関係なく、Cロケールになります(または、それ以上に選択肢を与えてください)。スレッドごとにグローバルロケールを設定する方法がない限り、strtoul、stoul、およびboost :: lexical_castは除外され、istringstream(ロケールを埋めることができる場所)だけが残されます。
  3. 合理的に厳格であること。それは間違いなく後続のゴミを受け入れてはならないし、理想的には空白も禁止したいと思う。それはすぐにstrtolとそれに基づく何かを少し問題にします。 istringstreamはここでnoskipwsを使って動作し、EOFをチェックすることができますが、これはGCCバグかもしれません。
  4. ベースが10であると仮定されるべきか、0または0xプレフィックスから推定されるべきであるかを理想的に制御します。

ソリューションに関するアイデアはありますか?これらの要件を満たすために既存の解析マシンを簡単にラッピングする方法はありますか、それとも、パーサを自分で作成する作業が少なくなるのでしょうか?

+0

機械で書かれた値が範囲外であるのはなぜですか? – andre

+1

は、あなた自身を開発する必要があると思われます。またはカスタムライブラリを見つける –

+1

@andre範囲の検証は、(人間によって書かれた)設定ファイル解析のためのものです。しかし、ネットワーク上で受信したデータを検証することも賢明です。 –

答えて

1

通常の(堅牢ではない)パーズと入力の小さなチェック(例えば、負でない数字のチェックで ' - '文字がないことなど)がある場合があります。

堅牢性の究極のテストは、整数をテキストに変換して、入力テキストと出力テキストが同じであることを確認することです。テキスト版で作業するときは、先行する0やスペースを受け入れるようなことを緩和することができます。

1

基本的にCロケールのnum_get<char>ファセットが必要です。多少複雑ですので、this exampleを参照してください。基本的には、use_facet<num_get<char,string::iterator> > (locale::classic).get(begin, end, ... , outputValue)に電話する必要があります。

+0

これは基本的にはそれはオペレータがフードの下で使用するものなので、istringstream。オーバーヘッドにいくらかの減少があるかもしれませんが、それでも負の値を受け入れてラップします。 –

+0

@BruceMerry:それは実際にオーバーヘッドをカットしています。それはボンネットの下で多くの異なる実装があるようにではありません。負の数値については、ラウンドトリップかどうかを確認してください:元の文字列を戻すことはできますか? – MSalters