使用isdigit比较unicode时调试断言失败,错误

问题描述 投票:1回答:3

[if statement时,我在i = 7中有调试断言错误:

Expression: c>= -1 && c <= 255

这是我的代码:

#include <iostream>
#include <string>

const char* clearString(std::string str)
{
    for (int i = str.length() - 1; i >= 0; i--)
    {
        if (  !isdigit(str[i])
            && str[i] != ',')
        {
            str.erase(i, 1);
        }
    }
    return str.c_str();
}

int main()
{
    std::string str = "688,13 €";

    std::cout << clearString(str);
}

我尝试删除字符串中不是数字和','的所有字符。

c++ string assert
3个回答
1
投票

关于std::isdigit,请参阅Notes section关于为什么得到断言的信息。

此修补程序将强制转换为unsigned char

if (!isdigit(static_cast<unsigned char>(str[i]))

其次,您的函数返回本地临时地址,因此表现出未定义的行为。返回std::string

std::string clearString(std::string str)
{
   //…
   return str;
}

第三,您可以使用std::remove_ifstd::string::erase重写函数,而不是编写一次删除字符的循环。

#include <algorithm>
//...
std::string clearString(std::string str)
{
    auto iter = std::remove_if(str.begin(), str.end(),
          [&](char ch) 
         { return !isdigit(static_cast<unsigned char>(ch)) && ch != ',';});
    str.erase(iter, str.end());
    return str;
}

1
投票

[isdigit()函数仅适用于其十进制值在-1到255之间的字符。

字符的十进制值为-128,该功能不支持。

我建议更改比较而不是使用isdigit(),比较字符的十进制值。

将功能更改为此:

const char* clearString(std::string& str)
{
    for (int i = str.length() - 1; i >= 0; i--)
    {
        if ((str[i] < '0' || str[i] > '9') && str[i] != ',')
        {
            str.erase(i, 1);
        }
    }
    return str.c_str();
}

1
投票

关于您的算法,有点不合时宜。

如果您不擦除每个非数字字符,而是将字符向左移动,跳过所有非数字字符(','除外)并调整字符串大小,会更好。

关于isdigit我将按照0xBlackMirror的建议进行操作,将其与'0'和'9'进行比较。

这里是代码:

const char* clearString(std::string str)
{
    int j = 0;
    for (uint i = 0; i < str.size(); i++)
    {
        if ((str[i] >= '0' && str[i] <= '9') || str[i] == ',')
        {
            str[j++] = str[i];
        }
    }
    str.resize(j);
    return str.c_str();
}
© www.soinside.com 2019 - 2024. All rights reserved.