繁体   English   中英

C++ 检查字符串是否包含数字和。 只有[关闭]

[英]C++ check if a string contains numbers and . only [closed]

我想知道是否有 lambda 或干净的短格式,以便查找单个字符串是否仅包含数值(例如 0 - 9)和句号(例如)。 例如,字符串“123.45”应该通过,而字符串“12jd”、“12.4f”等应该失败。

这将是您检查的代码,constexpr 的东西使 function 在编译时可评估。 并且 static_assert 在编译时检查 output。 基本上在编译时进行单元测试。

string_view 是一个很好的字符串文字包装器,它使字符串文字更容易传递到 function 中,并允许使用基于范围的 for 循环来遍历所有字符。

#include <cassert>
#include <string_view>

constexpr bool is_positive_number(const std::string_view number_string)
{
    std::size_t number_of_points{ 0ul };

    // loop over all characters in string
    for (const auto character : number_string)
    {
        // a '.' is valid but there should only be one
        if (character == '.')
        {
            number_of_points++;
            if (number_of_points > 1) return false;
        }
        else
        {
            // if character is not a '.' then it must be betweern '0'-'9'
            if ((character < '0') || (character > '9')) return false;
        }
    }

    return true;
}

int main()
{
    static_assert(is_positive_number("1"));
    static_assert(is_positive_number("12"));
    static_assert(is_positive_number("123"));
    static_assert(is_positive_number("1."));
    static_assert(is_positive_number("1.2"));
    static_assert(is_positive_number("12.34"));
    static_assert(is_positive_number("007"));

    static_assert(!is_positive_number("12.3.4"));
    static_assert(!is_positive_number("-123"));
    static_assert(!is_positive_number("abc"));

    //auto lambda = [](const char* number_string)
    auto lambda = [](const std::string& number_string)
    {
        return is_positive_number(number_string);
    };

    auto is_ok = lambda("123");
    assert(is_ok);


    return 0;
}

这可以通过直接扫描文本来完成:

bool is_valid(const std::string& str) {
    int dots = 0;
    for (char c: str) {
        if (c == '.')
            ++dots;
        if (1 < dots || !std::isdigit(c))
            return false;
    }
    return true;
}

另一种方法是使用开源 编译时正则表达式库

#include <ctre.hpp>

constexpr bool is_positive_number(std::string_view const s) noexcept {
    return static_cast<bool>(ctre::match<R"(\d+(?:\.\d+)?)">(s));
}

int main() {
    static_assert(is_positive_number("1.2"));
    static_assert(!is_positive_number("1..2"));
    static_assert(!is_positive_number("1e2"));
}

在线查看

如果您不计算 static 模式,则使用 std::regex 会产生两行

#include <string>
#include <regex>
#include <cassert>

bool is_positive_number( const std::string& str ) {
    static std::regex rx("^(\\+?)(0|([1-9][0-9]*))(\\.[0-9]*)?$");             // Getting the regex object 
    std::smatch match;
    return std::regex_match(str,match,rx);
}

int main()
{
    assert(is_positive_number("1"));
    assert(is_positive_number("12"));
    assert(is_positive_number("123"));
    assert(is_positive_number("1."));
    assert(is_positive_number("1.2"));
    assert(is_positive_number("12.34"));
    assert(is_positive_number("+12.34"));
    assert(!is_positive_number("007"));

    assert(!is_positive_number("123.23.23"));
    assert(!is_positive_number("-123"));
    assert(!is_positive_number("abc"));

    return 0;
}

这不会像重复点一样检查所有情况,但它是单行的

  bool ok = str.find_first_not_of( "0123456789." )==std::string::npos;

使用如

#include <algorithm>
#include <string>

constexpr bool is_positive_number( const std::string_view& str ) {
    return str.find_first_not_of( "0123456789." )==std::string::npos;
}

int main()
{
    static_assert(is_positive_number("1"));
    static_assert(is_positive_number("12"));
    static_assert(is_positive_number("123"));
    static_assert(is_positive_number("1."));
    static_assert(is_positive_number("1.2"));
    static_assert(is_positive_number("12.34"));
    static_assert(is_positive_number("007"));

    static_assert(!is_positive_number("-123"));
    static_assert(!is_positive_number("abc"));

    return 0;
}

我不认为有一个内置的 function 完全符合您的要求。 std::stodstring转换为double精度并告诉您成功转换了多少个字符。 但是,有许多不合格的数字会起作用,例如-1NAN10E+3


您可以做的一种方法是首先删除所有数字(0~9),然后检查"""."

constexpr bool is_num(std::string str)
{
    std::erase_if(str, [](unsigned char c){ return std::isdigit(c);};
    return str == "" || str == ".";
}

注意erase_if来自 C++20,对于 C++20 之前的版本,您可以:

constexpr bool is_num(std::string str)
{
    str.erase(std::remove_if(str.begin(), str.end(), 
              [](unsigned char c){ return std::isdigit(c); }), str.end());
    return str == "" || str == ".";
}

演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM