"std::isdigit"正在崩溃几个扩展的 ASCII 字符

"std::isdigit" is crashing for few extended ASCII Chars

本文关键字:几个 扩展 字符 ASCII isdigit std 崩溃      更新时间:2023-10-16

由于一些要求,我需要遍历一个字符串以查看字符串中是否存在任何数字。

当我尝试下面的代码时,在我的测试过程中,应用程序崩溃了。经过仔细观察,我注意到输入字符串具有特殊字符(扩展 ASCII 字符(。

#include <iostream>
#include <string>
#include <algorithm>
int main()
{
    std::string wordstr("tes¶¶"); //
    //int num  = unsigned char('¶'); // ASCII 182 (DEC)
    //int num1  = unsigned char('T'); // ASCII 84 (DEC)
    std::find_if(wordstr.begin(), wordstr.end(), ::isdigit) != wordstr.end();  
    return 0;
}

为什么扩展的 ASCII 值std::isdigit崩溃?(尝试过很少(。

是否有任何替代标准函数可以查找字符是否为数字,如果我的输入字符串中有特殊字符,它不会崩溃?

注意:由于此代码库的维护问题,我不应该使用 C++11 及更高版本。

<ctype.h>分类函数名义上接受int,但输入值必须表示为unsigned char或特殊值EOF。所有其他输入都会导致未定义的行为。C11 §7.4p1:

在所有情况下,参数都是一个int,其值应为 可表示为unsigned char或应等于 宏EOF .如果参数具有任何其他值,则行为为 定义。

C++继承了这个限制。解决方案是在将任何普通char参数传递给unsigned char(而不是unsigned!(之前将其传递给::isdigit,或者在<locale>中使用C++区域设置感知重载。

在我们的

服务器代码中接收电子邮件文本时,我std::isspace()面临类似的崩溃。在搜索互联网时,我偶然发现了这篇文章。似乎对于所有<cctype>方法,都必须进行类型转换才能unsigned char

找到如下参考资料:

像 中的所有其他函数一样,如果参数的值既不能表示为无符号字符,也不能等于 EOF,则 std::isdigit (std::isxxx( 的行为是未定义的。要安全地将这些函数与纯字符(或有符号字符(一起使用,应首先将参数转换为无符号字符:
bool my_isdigit(char ch) {return std::isdigit(static_cast<unsigned char>(ch));}