2013-03-22 80 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

相關問題