2017-03-16 7 views
1

stringstream(またはistringstreamやその他のStd-C++クラス)で数値(10進数と16進数)を解析するための、簡単で洗練された方法を探しています。C++:stringstream parsing

たとえば10進数の有効な入力。 11は、通常、私は正規表現を使用しますが、それが原因で不足しているライブラリのとC++コンパイラオーデルここでは可能ではない BH

0xb でなければなりません。

ありがとうございます!

+0

[std :: strtol](http://en.cppreference.com/w/cpp/string/byte/strtol) – Galik

答えて

2

それは愚かなことかもしれませんが、私見最も簡単な解決策はstd::stringstream + std::hex(およびothers)である

unsigned int x; 
std::stringstream ss; 
ss << std::hex << "0xb"; 
ss >> x; 
+0

私は考えが複雑だと思っていました。 – chris01

+0

OP: '11 0xb bh 'で定義された入力に対して一般的に機能しません。入力 '11'に対してxを '17 'に設定します。 – zett42

+0

@ zett42私のコードは、16進文字列の単なる例です。私は、 '11 0xb bh 'は3つの異なる番号システムで3つの可能な入力であったと思います。私がリンクしたリンクには、これらのシステムのためのマニピュレータがあります。そして、OPのコメントから、この答えに私はそれが彼を助けたと結論づけます - それが目標でした。 – stryku

0

私は何かが欠落している可能性がありますが、私はデフォルトistream::operator >>は、入力から自動的にベースを検出することができないと思われます。マニピュレータstd::hexは、にのみ使用することができます。から16までは、接頭辞 "0x"または接尾辞 "h"に関係なくすべての入力に適用されます。

私たちは、カスタムタイプのためoperator >>に過負荷をかけることで回避してstd::stoi()を呼び出すことができます。

struct ParsedInt 
{ 
    int val; 
}; 

inline std::istream& operator>>(std::istream& strm, ParsedInt& i) 
{ 
    std::string s; strm >> s; 
    i.val = 0; 

    if(! s.empty()) 
    { 
     if(s.back() == 'h') 
      // explicitly use base 16 to parse hex 
      i.val = static_cast<int>(std::stoul(s, nullptr, 16)); 
     else 
      // stoi() with base 0 will detect prefix "0x". 
      i.val = static_cast<int>(std::stoul(s, nullptr, 0)); 
    } 

    return strm; 
} 

使用例:

int main() 
{ 
    std::stringstream ss("11 0xb bh -11 0xffffffff fffffffeh"); 

    ParsedInt i; 
    while(ss >> i) 
    { 
     std::cout << i.val << "\n"; 
    } 
} 

出力:

11 
11  
11  
-11  
-1  
-2 

Live Demo

編集:オリジナルのコードは0xFFFFFFFFのような負の16進数のためのstd::out_of_rangeの例外を除いて墜落した

、これはintに結果をINGのstd::stoul()static_caststd::stoi()を交換することによって修正されました。