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

C++StringPattern Matching

C++ Problem Overview


Or from the other way around find first non digit character.

Do the same functions apply for string and for char* ?

C++ Solutions


Solution 1 - C++

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
}

Solution 2 - C++

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:

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>:

> ... In all cases the argument is an int, the value of which shall be representable as an unsigned char or shall equal the value of the macro EOF. If the argument has any other value, the behavior is undefined.

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:

> ... It is implementation-defined whether a char object can hold negative values. ...

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.

Now, why does the conversion to unsigned char does the right things?

According to 4.7 [conv.integral] paragraph 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 ]

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.

Solution 3 - C++

isdigit(int) tells you if a character is a digit. If you are going to assume ASCII and base 10, you can also use:

int first_non_digit_offset= strspn(string, "0123456789")

Solution 4 - C++

In the same spirit as Misha's answer, but more correct: 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.

Solution 5 - C++

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.

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):

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

Solution 6 - C++

#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

Solution 7 - C++

From the [cplusplus.com][1] you can use isdigit function as follow:

// 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. [1]: http://www.cplusplus.com/reference/locale/isdigit/

Solution 8 - C++

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionrsk82View Question on Stackoverflow
Solution 1 - C++BlastfurnaceView Answer on Stackoverflow
Solution 2 - C++Dietmar KühlView Answer on Stackoverflow
Solution 3 - C++MSNView Answer on Stackoverflow
Solution 4 - C++MSaltersView Answer on Stackoverflow
Solution 5 - C++paxdiabloView Answer on Stackoverflow
Solution 6 - C++Shakiba MoshiriView Answer on Stackoverflow
Solution 7 - C++sh.e.salhView Answer on Stackoverflow
Solution 8 - C++YuushiView Answer on Stackoverflow