如何检查给定的 C++ 字符串或字符 * 是否只包含数字?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8888748/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to check if given c++ string or char* contains only digits?
提问by rsk82
Or from the other way around find first non digit character.
或者反过来查找第一个非数字字符。
Do the same functions apply for string and for char* ?
相同的函数是否适用于 string 和 char* ?
回答by Blastfurnace
Of course, there are many ways to test a string for only numeric characters. Two possible methods are:
当然,有很多方法可以测试字符串是否只包含数字字符。两种可能的方法是:
bool is_digits(const std::string &str)
{
return str.find_first_not_of("0123456789") == std::string::npos;
}
or
或者
bool is_digits(const std::string &str)
{
return std::all_of(str.begin(), str.end(), ::isdigit); // C++11
}
回答by Dietmar Kühl
Several people already mentioned to use isdigit()
. However, note that this isn't entirely trivial because char
can be signed which would cause a negative value to be passed to isdigit()
. However, this function can only take positive values. That is, you want something akin to this:
有几个人已经提到要使用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";
}
It seems the reasoning for the conversion to unsigned char
isn't obvious. So, here are the relevant quotes from their respective standards:
似乎转换为的unsigned char
原因并不明显。因此,以下是来自各自标准的相关引用:
According to ISO/IEC 9899:2011 (or ISO/IEC 9899:1999) 7.4 paragraph 1 the following applies to the arguments of the functions from <ctype.h>
:
根据 ISO/IEC 9899:2011(或 ISO/IEC 9899:1999)7.4 第 1 段,以下适用于以下函数的参数<ctype.h>
:
... In all cases the argument is an
int
, the value of which shall be representable as anunsigned char
or shall equal the value of the macroEOF
. If the argument has any other value, the behavior is undefined.
...在所有情况下,参数都是 an
int
,其值应表示为 anunsigned char
或应等于宏的值EOF
。如果参数有任何其他值,则行为未定义。
Unfortunately, the C++ standard doesn't specify that char
is an unsigned type. Instead it specifies in ISO/IEC 14882:2011 3.9.1 [basic.fundamental] paragraph 1:
不幸的是,C++ 标准没有指定它char
是无符号类型。相反,它在 ISO/IEC 14882:2011 3.9.1 [basic.fundamental] 第 1 段中指定:
... It is implementation-defined whether a
char
object can hold negative values. ...
...
char
对象是否可以包含负值是实现定义的。...
Clearly, a negative value cannot be represented as an unsigned char
. That is, if char
is using a signed type on an implementation (there are actually several which do, e.g., it is signed on MacOS using gcc or clang) there is the danger that calling any of the <ctype.h>
function would cause undefined behavior.
显然,负值不能表示为unsigned char
。也就是说,如果char
在一个实现上使用签名类型(实际上有几个这样做,例如,它在 MacOS 上使用 gcc 或 clang 签名),则调用任何<ctype.h>
函数都有可能导致未定义的行为。
Now, why does the conversion to unsigned char
does the right things?
现在,为什么转换为unsigned char
正确的事情?
According to 4.7 [conv.integral] paragraph 2:
根据 4.7 [conv.integral] 第 2 段:
If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2nwhere n is the number of bits used to represent the unsigned type). [ Note: In a two's complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation). —end note ]
如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模 2 n,其中 n 是用于表示无符号类型的位数)。[ 注意:在二进制补码表示中,这种转换是概念性的,位模式没有变化(如果没有截断)。——尾注]
That is, the conversion from a [potentially] signed char
to unsigned char
is well-defined and causes the result to be in the permitted range for the <ctype.h>
functions.
也就是说,从 [潜在] 有符号char
到的转换unsigned char
是明确定义的,并且导致结果在<ctype.h>
函数的允许范围内。
回答by MSN
isdigit(int)
tells you if a character is a digit. If you are going to assume ASCII and base 10, you can also use:
isdigit(int)
告诉你一个字符是否是数字。如果您打算使用 ASCII 和基数 10,您还可以使用:
int first_non_digit_offset= strspn(string, "0123456789")
回答by MSalters
In the same spirit as Misha's answer, but more correct: sscanf(buf, "%*u%*c")==1
.
本着同样的精神作为Misha的答案,但更正确的:sscanf(buf, "%*u%*c")==1
。
scanf
returns 0 if the %d
digit extraction fails, and 2 if there is anything after the digits captured by %c
. And since *
prevents the value from being stored, you can't even get an overflow.
scanf
如果%d
数字提取失败,则返回 0,如果%c
. 并且由于*
防止存储值,您甚至不能得到溢出。
回答by paxdiablo
The cctype
header file has a good number of character classifications functions which you can use on each character in the string. For numeric checks, that would be isdigit
.
在cctype
头文件中有相当数量的,你可以在字符串中的每个字符使用字符分类功能。对于数字检查,那将是isdigit
.
The following program shows how to check each character of a C or C++ string ( the process is pretty much identical in terms of checking the actual characters, the only real difference being how to get the length):
以下程序显示了如何检查 C 或 C++ 字符串的每个字符(检查实际字符的过程几乎相同,唯一真正的区别是如何获取长度):
#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;
}
回答by newComer
From the cplusplus.comyou can use isdigit function as follow:
从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;
}
Note: there is 2 types of isdigit the other version is local independent and ASCII based.
注意:isdigit 有两种类型,另一种是本地独立的,基于 ASCII 的。
回答by Shakiba Moshiri
#include <regex>
#include <regex>
std::string string( "I only have 3 dollars!" );
std::cout << std::regex_search( string, std::regex( "\d+" ) ); // true
and
和
std::string string( "I only have three dollars!" );
std::cout << std::regex_search( string, std::regex( "\d+" ) ); // false
回答by Yuushi
If it's a strict requirement that you can find exactly where the first non-character digit is, then you'll have to check each character. If not, I'd use either something like this:
如果严格要求您可以准确找到第一个非字符数字的位置,那么您必须检查每个字符。如果没有,我会使用这样的东西:
unsigned safe_atoi(const std::string& a)
{
std::stringstream s(a);
unsigned b;
s >> b;
return b;
}