如何检查给定的c ++字符串或char*是否只包含数字?

rsk*_*k82 45 c++ string pattern-matching

或者从另一个方向找到第一个非数字字符.

相同的函数是否适用于字符串和char*?

Bla*_*ace 96

当然,有很多方法可以仅为数字字符测试字符串.两种可能的方法是:

bool is_digits(const std::string &str)
{
    return str.find_first_not_of("0123456789") == std::string::npos;
}
Run Code Online (Sandbox Code Playgroud)

要么

bool is_digits(const std::string &str)
{
    return std::all_of(str.begin(), str.end(), ::isdigit); // C++11
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么这里是isdigit的双冒号?没有它就不能编译,`std :: isdigit`也不起作用. (4认同)
  • @AmitUpadhyay:我使用引用来避免复制传递的 `std::string` 参数(复制可能会很昂贵)。它们也是 `const` 以确保我不会修改调用者的变量。以这种方式使用 const 引用在 C++ 编程中很常见。 (3认同)
  • @Dfr:有多个`isdigit`函数(来自`<cctype>`和`<locale>`headers).[见这个相关的答案.](http://stackoverflow.com/a/13262555/445976) (2认同)
  • 老实说,c++11 的方式很摇滚:) (2认同)

Die*_*ühl 12

有几个人已经提到要使用isdigit().但请注意,这并非完全无关紧要,因为char可以签名,这会导致负值传递给isdigit().但是,此功能只能采用正值.也就是说,你想要类似于此的东西:

if (s.end() == std::find_if(s.begin(), s.end(),
    [](unsigned char c)->bool { return !isdigit(c); })) {
    std::cout << "string '" << s << "' contains only digits\n";
}
Run Code Online (Sandbox Code Playgroud)

似乎转换的unsigned char原因并不明显.所以,以下是各自标准的相关引用:

根据ISO/IEC 9899:2011(或ISO/IEC 9899:1999)7.4第1段,以下内容适用于以下功能的论点<ctype.h>:

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

不幸的是,C++标准没有指定它char是无符号类型.相反,它在ISO/IEC 14882:2011中指定3.9.1 [basic.fundamental]第1段:

...实现定义char对象是否可以保存负值....

显然,负值不能表示为unsigned char.也就是说,如果char在实现上使用带符号的类型(实际上有几个做了,例如,它使用gcc或clang在MacOS上进行了签名),则调用任何<ctype.h>函数都会导致未定义的行为.

现在,为什么转换unsigned char做正确的事情?

根据4.7 [conv.integral]第2段:

如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模2 n,其中n是用于表示无符号类型的位数).[注意:在二进制补码表示中,此转换是概念性的,并且位模式没有变化(如果没有截断). - 尾注]

也就是说,从[可能]签名char到的转换unsigned char是明确定义的,并导致结果在<ctype.h>函数的允许范围内.

  • 从`char`到`unsigned char`的转换不会溢出或任何东西.它将保留原始位,但在`isdigit()`的定义范围内产生一个值,即使`char`被签名且字符在负范围内.相关引用见C的7.4第1段. (2认同)

MSN*_*MSN 5

isdigit(int)告诉你角色是否是数字.如果您要假设ASCII和基数为10,您还可以使用:

int first_non_digit_offset= strspn(string, "0123456789")
Run Code Online (Sandbox Code Playgroud)


MSa*_*ers 5

本着同样的精神作为Misha的答案,但更正确的:sscanf(buf, "%*u%*c")==1

scanf如果%d数字提取失败,则返回 0,如果%c. 并且由于*防止存储值,您甚至不能得到溢出。