如何检查给定的 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 19:16:55  来源:igfitidea点击:

how to check if given c++ string or char* contains only digits?

c++stringpattern-matching

提问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 charcan 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 charisn'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 an unsigned charor shall equal the value of the macro EOF. If the argument has any other value, the behavior is undefined.

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

Unfortunately, the C++ standard doesn't specify that charis 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 charobject can hold negative values. ...

...char对象是否可以包含负值是实现定义的。...

Clearly, a negative value cannot be represented as an unsigned char. That is, if charis 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 chardoes 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 charto unsigned charis 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

scanfreturns 0 if the %ddigit 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 cctypeheader 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;
}