是否有stl或boost函数来确定字符串是否为数字

Is there a stl or boost function to determine if a string is numeric?

本文关键字:是否 字符串 数字 函数 stl boost      更新时间:2023-10-16

我对C++、boost等很陌生

我想知道boost或STL中是否已经有一个函数可以用来确定字符串是否为数字。

数字字符串可能如下所示:100

100.52

我知道有很多关于如何编写这样一个函数的例子,但我想知道是否已经有一个函数可以用于此。

我正在寻找一个纯粹的C++解决方案,而不是C.

[更新:我已经在使用lexical_cast来转换我的字符串,我只是想知道是否有像is_numeric这样的方法可以用于此…]

不,没有现成的方法可以直接做到这一点。

您可以使用boost::lexical_cast<double>(your_string)std::stod(your_string),如果它抛出异常,则您的字符串不是双精度字符串。

C++11:

    bool is_a_number = false;
    try
    {
        std::stod(your_string);
        is_a_number = true;
    }
    catch(const std::exception &)
    {
        // if it throws, it's not a number.
    }

提升:

    bool is_a_number = false;
    try
    {
        lexical_cast<double>(your_string);
        is_a_number = true;
    }
    catch(bad_lexical_cast &)
    {
        // if it throws, it's not a number.
    }
可以使用

boost::regex(或std::regex,如果您有C++0x(;您可以定义您想要接受的内容(例如,在您的上下文中,"0x12E"是否为数字?(。对于C++整数:

"\s*[+-]?([1-9][0-9]*|0[0-7]*|0[xX][0-9a-fA-F]+)"

对于C++浮点:

"\s*[+-]?([0-9]+\.[0-9]*([Ee][+-]?[0-9]+)?|\.[0-9]+([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+)"

但根据你正在做的事情,你可能不需要支持那些复杂的事情。你举的两个例子是覆盖

"[0-9]+(\.[0-9]*)?"

例如。

如果您稍后需要该数值,它也可能是同样容易将字符串转换为istringstream,并且立即进行转换。如果没有错误提取所有的字符,字符串是一个数字;如果不是,事实并非如此。这会让你对确切的但是,您要接受的格式。

如果性能是个问题,我会使用boost.spirit.ki而不是std::stringstream:

#include <string>
#include <boost/spirit/include/qi_parse.hpp>
#include <boost/spirit/include/qi_numeric.hpp>
bool is_numeric(std::string const& str)
{
    std::string::const_iterator first(str.begin()), last(str.end());
    return boost::spirit::qi::parse(first, last, boost::spirit::double_)
        && first == last;
}

如果您想允许尾随空白,请执行以下操作:

#include <string>
#include <boost/spirit/include/qi_parse.hpp>
#include <boost/spirit/include/qi_numeric.hpp>
#include <boost/spirit/include/qi_char_class.hpp>
#include <boost/spirit/include/qi_operator.hpp>
bool is_numeric(std::string const& str)
{
    std::string::const_iterator first(str.begin()), last(str.end());
    return boost::spirit::qi::parse(first, last,
            boost::spirit::double_ >> *boost::spirit::qi::space)
        && first == last;
}

如果转换"ate"了原始字符串(=eof()(中的所有字符,则使用stringstream并返回true

bool is_numeric(const std::string& str) {
    std::stringstream conv;
    double tmp;
    conv << str;
    conv >> tmp;
    return conv.eof();
}
bool is_numeric(std::string number)
{
    char* end = 0;
    std::strtod(number.c_str(), &end);
    return end != 0 && *end == 0;
}

bool is_integer(std::string number)
{
    return is_numeric(number.c_str()) && std::strchr(number.c_str(), '.') == 0;
}

以下代码

下面的句子,如果"str"仅由0~9组成,则返回true,否则返回false。

return str.find_first_not_of("0123456789") == std::string::npos

您可以在字符串上尝试lexical_cast。

从C++11,您可以简单地使用std::stofstd::stodstd::stold中的一个分别转换为floatdoublelong double。如果出现问题,他们会将字符串转换为数值,或者抛出异常(请参阅参考资料(。以下是std::stod:的示例

bool isNumeric(const std::string& str) {
  try {
    std::stod(str); // can safely ignore the return value, function is not [[nodiscard]]
    return true;
  }
  catch (const std::exception&) {
    return false;
  }
}

还可以看看将字符串转换为有符号和无符号整数的函数。

不需要升压,只需要stl。。。单个字符可以被检查为int(c>='0'&c<='9'(,find_if_not将发现第一个字符与[first]和[last]之间的条件不匹配。如果没有找到匹配项,它将返回[最后]。

如果额外的字符像空格,.-应该检查,添加它们。

#include <string>
#include <algorithm>
bool isNumeric(std::string strValue) 
{
    if (strValue.empty())
        return false;
    else
        return (std::find_if_not( std::begin(strValue)
                            , std::end(strValue)
                            , [](char c)
                              { return (c >= '0' && c <= '9'); }
                            ) == std::end(strValue)
                );
}

p.S。@胡是一个空字符串数字吗?