Or from the other way around find first non digit character.
或者从另一种角度来看第一个非数字字符。
Do the same functions apply for string and for char* ?
同样的函数是否适用于字符串和char* ?
8 个解决方案
#1
83
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
}
#2
10
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:
看起来,转换到无符号字符的原因并不明显。因此,以下是他们各自标准的相关报价:
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/ iec9899:2011(或ISO/IEC 989:1999) 7.4第1款,以下适用于
... 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.…在所有情况下,参数都是int型的,其值应被表示为无符号字符,或等于宏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/ iec14882:2011 3.9.1 [basic。基本]段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.
显然,负值不能表示为无符号字符。也就是说,如果char在实现上使用已签名的类型(实际上有几个这样的类型,例如,它在使用gcc或clang的MacOS上签名),那么就有调用任何
Now, why does the conversion to unsigned char
does the right things?
现在,为什么转换为无符号字符会做正确的事情呢?
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 2n where 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 ]
如果目标类型是未签名的,则产生的值是源整数的最小无符号整数(模2n,其中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的转换被定义良好,并使结果处于
#3
5
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")
#4
4
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.
如果%d的数字提取失败,那么scanf返回0,如果在%c捕获的数字后面有任何数字,则返回2。由于*阻止了存储的值,所以您甚至不能得到溢出。
#5
3
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;
}
#6
0
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;
}
#7
0
#include <regex>
# include <正则表达式>
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
#8
0
From the cplusplus.com you 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的。
#1
83
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
}
#2
10
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:
看起来,转换到无符号字符的原因并不明显。因此,以下是他们各自标准的相关报价:
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/ iec9899:2011(或ISO/IEC 989:1999) 7.4第1款,以下适用于
... 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.…在所有情况下,参数都是int型的,其值应被表示为无符号字符,或等于宏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/ iec14882:2011 3.9.1 [basic。基本]段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.
显然,负值不能表示为无符号字符。也就是说,如果char在实现上使用已签名的类型(实际上有几个这样的类型,例如,它在使用gcc或clang的MacOS上签名),那么就有调用任何
Now, why does the conversion to unsigned char
does the right things?
现在,为什么转换为无符号字符会做正确的事情呢?
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 2n where 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 ]
如果目标类型是未签名的,则产生的值是源整数的最小无符号整数(模2n,其中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的转换被定义良好,并使结果处于
#3
5
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")
#4
4
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.
如果%d的数字提取失败,那么scanf返回0,如果在%c捕获的数字后面有任何数字,则返回2。由于*阻止了存储的值,所以您甚至不能得到溢出。
#5
3
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;
}
#6
0
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;
}
#7
0
#include <regex>
# include <正则表达式>
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
#8
0
From the cplusplus.com you 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的。