C++ 快速确定字符串是否为JSON编号的方法

C++ 快速确定字符串是否为JSON编号的方法,c++,json,C++,Json,检查不得使用C++11功能或其他库,例如Boost、Regex等。我提出了以下解决方案。不漂亮,但工作。从这里开始它会变得更优雅和/或更快吗 bool isJsonNumber(const std::string& text) { if(text.empty()) return false; bool foundE = false; bool foundESign = false; bool leadingZero = false; bool l

检查不得使用C++11功能或其他库,例如Boost、Regex等。我提出了以下解决方案。不漂亮,但工作。从这里开始它会变得更优雅和/或更快吗

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;
}
bool isJsonNumber(const std::string&text)
{
if(text.empty())返回false;
bool-foundE=false;
bool-foundESign=false;
bool leadingZero=错误;
bool lastIsDigit=false;
bool foundDot=false;
对于(uint32_t i=0;i'9');
如果(i==0)
{
if(currIsNoDigit&&c!='-')返回false;
如果(c='0')引导零=真;
如果(c!='-')lastIsDigit=true;
}
其他的
{
中频(零导)
{
前导零=假;
如果(c!='.')返回false;
foundDot=true;
}
else如果(c=='。)
{
如果(foundDot)返回false;
foundDot=true;
}
else if(c=='e'| | c=='e')
{
如果(发现)返回错误;
foundE=true;
}
else if(foundE&!foundESign)
{
if(currIsNoDigit&&c!='-'&&c!='+')返回false;
如果(c=='+'| | c=='-')
{
foundESign=true;
}
其他的
{
lastIsDigit=true;
}
}
其他的
{
foundESign=false;
如果(currIsNoDigit)返回false;
lastIsDigit=true;
}
}
}
if(lastIsDigit==false)返回false;
返回true;
}

用例是一个小型嵌入式服务器,它接收巨大的CSV文件和包含JSON部分的anwsers客户端。

它可能更易于使用:


如果您没有std::stod,因为它是C++11的一个特性,那么您可以对它执行类似的操作


如果要禁止
无穷大
NAN
或十六进制浮点值,只需检查字符串中的第二个或第三个字符是否为字母即可:

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

对于“较大”的数值,始终存在
std::stold
std::strtold
。但是,如果您想要任意大小的数字,那么可以像现在这样做,或者使用库,例如(这似乎是一个很好的函数)。

JSON规范描述的任意大小的数字可以超过一个双精度的大小。此外,无穷大和NaN是数字的不允许值,十六进制数字也是如此。另外,std::stod是C++11函数std::strtod不适合验证JSON编号。该规范可在RFC 4627中找到。OP的版本(可能)还可以。(假设有相应的单元测试;))
if ((text.length() > 2 && std::isalpha(text[1])) ||
    (text.length() > 3 && std::isalpha(text[2])))
{
    // Not a number
}