由于一些要求,我需要遍历字符串以查看字符串中是否存在任何数字。
当我尝试下面的代码时,在我的测试中,应用程序崩溃了......仔细观察后,我注意到输入字符串有特殊字符(扩展的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;
}
为什么std::isdigit
会因扩展的ASCII值而崩溃? (很少尝试)。
是否有任何替代标准函数来查找字符是否为数字,如果我的输入字符串中有特殊字符,它将不会崩溃?
注意:由于此代码库的维护问题,我不应该使用C ++ 11及更高版本。
答案 0 :(得分:5)
<ctype.h>
分类函数名义上接受int
,但输入值必须可以表示为unsigned char
或者是特殊值EOF
。所有其他输入都会导致未定义的行为。 C11§7.4p1:
在所有情况下,参数都是
int
,其值应为。{1}} 可表示为unsigned char
或等于的值 宏EOF
。如果参数具有任何其他值,则行为为 未定义。
C ++继承了这个限制。解决方案是将任何普通char
参数转换为unsigned char
(不是unsigned
!),然后再将其传递给::isdigit
,或者使用<locale>
中的C ++语言环境感知重载。 1}}。
答案 1 :(得分:1)
在我们的服务器代码中接收电子邮件文本时,std::isspace()
面临类似的崩溃。在搜索互联网时,我偶然发现了这篇文章。似乎对于所有<cctype>
方法,都必须将其类型转换为unsigned char
。
发现了一个reference,如下所示:
与参数中的所有其他函数一样,如果
std::isdigit
(std::isxxx
)的行为为 undefined ,则该参数的值也不能表示为无符号字符也不等于EOF
。为了安全地将这些函数与纯字符(或带符号的字符)一起使用,应首先将参数转换为无符号字符:
bool my_isdigit(char ch) {return std::isdigit(static_cast<unsigned char>(ch));}