C++:stringstream解析

问题描述:

我正在寻找一个简单和优雅的方式来解析数字(十进制和十六进制)stringstream(或istringstream或一些其他的Std-C++类)。C++:stringstream解析

有效输入的十进制数例如11应该是 0XB BH

通常我会使用一个正则表达式,但它是不可能的,因为这里缺少库和奥得C++编译器。

谢谢!

+0

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

这可能是愚蠢的,但恕我直言,最简单的解决方法是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我的代码只是一个十六进制字符串的例子。我认为'11 0xb bh'只是三种不同数字系统中的三种可能的输入。在我发布的链接中有这些系统的操纵器。从OP的评论到这个答案,我总结说它帮助了他 - 那就是目标。 – stryku

我可能失去了一些东西,但我认为,默认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

编辑:

原始代码开车撞std::out_of_range例外像0xFFFFFFFF负进制数,这已得到修复与std::stoul()static_cast荷兰国际集团的结果int更换std::stoi()