如何检查给定的c + +string或字符*只包含数字?

或者从相反的方向find第一个非数字字符。

相同的函数是否适用于string和char *?

当然,有很多方法只用数字字符来testing一个string。 两种可能的方法是:

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

要么

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

有几个人已经提到要使用isdigit() 。 但是请注意,这并不是微不足道的,因为可以对char进行签名,从而将负值传递给isdigit() 。 但是,这个function只能取正值。 也就是说,你想要类似这样的东西:

 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"; } 

看来转换为unsigned char原因并不明显。 所以,这里是他们各自标准的相关引用:

根据ISO / IEC 9899:2011(或ISO / IEC 9899:1999)7.4段落1,以下适用于来自<ctype.h>的函数的参数:

…在所有情况下,参数都是一个int值,它的值可以表示为一个unsigned char或者等于macrosEOF的值。 如果参数具有任何其他值,则行为是未定义的。

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

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

显然,负值不能表示为unsigned char 。 也就是说,如果char在一个实现上使用签名types(实际上有几个这样做,例如,它使用gcc或clang在MacOS上签名),那么调用任何<ctype.h>函数都会导致未定义的行为。

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

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

如果目标types是无符号的,则结果值是与源整数相等的最小无符号整数(模2 n ,其中n是用于表示无符号types的位数)。 [注意:在二进制补码表示中,这种转换是概念性的,位模式没有变化(如果没有截断)。 – 注意]

也就是说,从[可能]有符号charunsigned char是很好定义的,并且使得结果在<ctype.h>函数的允许范围内。

isdigit(int)告诉你一个字符是否是一个数字。 如果你要假设ASCII和10,你也可以使用:

 int first_non_digit_offset= strspn(string, "0123456789") 

正如Misha的回答一样,但更正确的是: sscanf(buf, "%*u%*c")==1

如果%d数字提取失败,则scanf返回0,如果%c捕获的数字之后有scanf返回2。 由于*阻止了存储的值,所以甚至无法获得溢出。

cctype头文件有很多字符分类函数,可以在string中的每个字符上使用。 对于数字检查,这将是isdigit

以下程序显示了如何检查C或C ++string的每个字符(在检查实际字符方面,这个过程几乎完全相同,唯一的区别是如何获得长度):

 #include <iostream> #include <cstring> #include <cctype> int main (void) { const char *xyzzy = "42x"; std::cout << xyzzy << '\n'; for (int i = 0; i < std::strlen (xyzzy); i++) { if (! std::isdigit (xyzzy[i])) { std::cout << xyzzy[i] << " is not numeric.\n"; } } std::string plugh ("3141y59"); std::cout << plugh << '\n'; for (int i = 0; i < plugh.length(); i++) { if (! std::isdigit (plugh[i])) { std::cout << plugh[i] << " is not numeric.\n"; } } return 0; } 

如果这是一个严格的要求,你可以find第一个非字符数字的确切位置,那么你将不得不检查每个字符。 如果没有,我会使用这样的东西:

 unsigned safe_atoi(const std::string& a) { std::stringstream s(a); unsigned b; s >> b; return b; } 

#include <regex>

 std::string string( "I only have 3 dollars!" ); std::cout << std::regex_search( string, std::regex( "\\d+" ) ); // true 

 std::string string( "I only have three dollars!" ); std::cout << std::regex_search( string, std::regex( "\\d+" ) ); // false 

从cplusplus.com你可以使用isdigit函数如下:

 // isdigit example (C++) #include <iostream> // std::cout #include <string> // std::string #include <locale> // std::locale, std::isdigit #include <sstream> // std::stringstream int main () { std::locale loc; std::string str="1776ad"; if (isdigit(str[0],loc)) { int year; std::stringstream(str) >> year; std::cout << "The year that followed " << year << " was " << (year+1) << ".\n"; } return 0; } 

注意:isdigit有两种types,其他版本是本地独立的和基于ASCII的。