2013-03-22 96 views
1

该检查不得使用用户C++ 11功能或其他库例如提升,正则表达式等我提出了以下解决方案。没有漂亮,但工作。它从这里变得更优雅和/或更快吗?确定字符串是否为JSON编号的快速方法

bool isJsonNumber(const std::string& text) 
{ 
    if(text.empty()) return false; 

    bool foundE = false; 
    bool foundESign = false; 
    bool leadingZero = false; 
    bool lastIsDigit = false; 
    bool foundDot = false; 

    for(uint32_t i=0; i < text.length(); ++i) 
    { 
     const unsigned char c = text[i]; 

     lastIsDigit = false; 
     const bool currIsNoDigit = (c < '0' || c > '9'); 

     if(i == 0) 
     { 
      if(currIsNoDigit && c != '-') return false; 
      if(c == '0') leadingZero = true; 
      if(c != '-') lastIsDigit = true; 
     } 
     else 
     { 
      if(leadingZero) 
      { 
       leadingZero = false; 
       if(c != '.') return false; 
       foundDot = true; 
      } 
      else if(c == '.') 
      { 
       if(foundDot) return false; 
       foundDot = true; 
      } 
      else if(c == 'e' || c == 'E') 
      { 
       if(foundE) return false; 
       foundE = true; 
      } 
      else if(foundE && !foundESign) 
      { 
       if(currIsNoDigit && c != '-' && c != '+') return false; 
       if(c == '+' || c == '-') 
       { 
        foundESign = true; 
       } 
       else 
       { 
        lastIsDigit = true; 
       } 
      } 
      else 
      { 
       foundESign = false; 
       if(currIsNoDigit) return false; 
       lastIsDigit = true; 
      } 
     } 
    } 

    if(lastIsDigit == false) return false; 

    return true; 
} 

该用例是一个小型的嵌入式服务器,它接收大量的CSV文件和带有JSON部分的awsers客户端。

回答

2

它可能会更容易使用std::stod

size_t endpos; 
std::stod(text, &endpos); 

if (endpos != text.length()) 
{ 
    // Not a number 
} 
else 
{ 
    // A number 
} 

如果你没有std::stod,因为它是一个C++ 11的功能,你可以做std::strtod类似的东西。


如果你想禁止INFINITYNAN或十六进制浮点值,它是作为检查字符串中的第二或第三个字符不是字母一样简单:

if ((text.length() > 2 && std::isalpha(text[1])) || 
    (text.length() > 3 && std::isalpha(text[2]))) 
{ 
    // Not a number 
} 

对于“大“numnbers总是std::stoldstd::strtold。然而,如果你想要任意大小的数字,那么要么像现在这样做,要么使用库如GMPmpf_set_str似乎是一个很好的功能)。

+0

JSON规范描述了可以超过双倍大小的任意大小的数字。 Infinity和NaN也不是数字的允许值,对于十六进制数字也是一样的。 std :: stod也是C++ 11 – aggsol 2013-03-22 09:39:08

+0

函数std :: strtod不适合验证JSON数字。规范可以在RFC 4627中找到。OP的版本(可能)是OK的。 (假设有相应的单元测试;)) – CouchDeveloper 2013-03-28 11:42:19

相关问题