[c++] How do I check if a C++ string is an int?

When I use getline, I would input a bunch of strings or numbers, but I only want the while loop to output the "word" if it is not a number. So is there any way to check if "word" is a number or not? I know I could use atoi() for C-strings but how about for strings of the string class?

int main () {
  stringstream ss (stringstream::in | stringstream::out);
  string word;
  string str;
  getline(cin,str);
  ss<<str;
  while(ss>>word)
    {
      //if(    )
        cout<<word<<endl;
    }
}

This question is related to c++ string types stringstream

The answer is


Ok, the way I see it you have 3 options.

1: If you simply wish to check whether the number is an integer, and don't care about converting it, but simply wish to keep it as a string and don't care about potential overflows, checking whether it matches a regex for an integer would be ideal here.

2: You can use boost::lexical_cast and then catch a potential boost::bad_lexical_cast exception to see if the conversion failed. This would work well if you can use boost and if failing the conversion is an exceptional condition.

3: Roll your own function similar to lexical_cast that checks the conversion and returns true/false depending on whether it's successful or not. This would work in case 1 & 2 doesn't fit your requirements.


If you're just checking if word is a number, that's not too hard:

#include <ctype.h>

...

string word;
bool isNumber = true;
for(string::const_iterator k = word.begin(); k != word.end(); ++k)
    isNumber &&= isdigit(*k);

Optimize as desired.


You can use boost::lexical_cast, as suggested, but if you have any prior knowledge about the strings (i.e. that if a string contains an integer literal it won't have any leading space, or that integers are never written with exponents), then rolling your own function should be both more efficient, and not particularly difficult.


Here is another solution.

try
{
  (void) std::stoi(myString); //cast to void to ignore the return value   
  //Success! myString contained an integer
} 
catch (const std::logic_error &e)
{   
  //Failure! myString did not contain an integer
}

I have modified paercebal's method to meet my needs:

typedef std::string String;    

bool isInt(const String& s, int base){
   if(s.empty() || std::isspace(s[0])) return false ;
   char * p ;
   strtol(s.c_str(), &p, base) ;
   return (*p == 0) ;
}


bool isPositiveInt(const String& s, int base){
   if(s.empty() || std::isspace(s[0]) || s[0]=='-') return false ;
   char * p ;
   strtol(s.c_str(), &p, base) ;
   return (*p == 0) ;
}


bool isNegativeInt(const String& s, int base){
   if(s.empty() || std::isspace(s[0]) || s[0]!='-') return false ;
   char * p ;
   strtol(s.c_str(), &p, base) ;
   return (*p == 0) ;
}

Note:

  1. You can check for various bases (binary, oct, hex and others)
  2. Make sure you don't pass 1, negative value or value >36 as base.
  3. If you pass 0 as the base, it will auto detect the base i.e for a string starting with 0x will be treated as hex and string starting with 0 will be treated as oct. The characters are case-insensitive.
  4. Any white space in string will make it return false.

Use the all-powerful C stdio/string functions:

int dummy_int;
int scan_value = std::sscanf( some_string.c_str(), "%d", &dummy_int);

if (scan_value == 0)
    // does not start with integer
else
    // starts with integer

You might try boost::lexical_cast. It throws an bad_lexical_cast exception if it fails.

In your case:

int number;
try
{
  number = boost::lexical_cast<int>(word);
}
catch(boost::bad_lexical_cast& e)
{
  std::cout << word << "isn't a number" << std::endl;
}

Since C++11 you can make use of std::all_of and ::isdigit:

#include <algorithm>
#include <cctype>
#include <iostream>
#include <string_view>

int main([[maybe_unused]] int argc, [[maybe_unused]] char *argv[])
{
    auto isInt = [](std::string_view str) -> bool {
        return std::all_of(str.cbegin(), str.cend(), ::isdigit);
    };

    for(auto &test : {"abc", "123abc", "123.0", "+123", "-123", "123"}) {
        std::cout << "Is '" << test << "' numeric? " 
            << (isInt(test) ? "true" : "false") << std::endl;
    }

    return 0;
}

Check out the result with Godbolt.


template <typename T>
const T to(const string& sval)
{
        T val;
        stringstream ss;
        ss << sval;
        ss >> val;
        if(ss.fail())
                throw runtime_error((string)typeid(T).name() + " type wanted: " + sval);
        return val;
}

And then you can use it like that:

double d = to<double>("4.3");

or

int i = to<int>("4123");

The accepted answer will give a false positive if the input is a number plus text, because "stol" will convert the firsts digits and ignore the rest.

I like the following version the most, since it's a nice one-liner that doesn't need to define a function and you can just copy and paste wherever you need it.

#include <string>

...

std::string s;

bool has_only_digits = (s.find_first_not_of( "0123456789" ) == std::string::npos);

EDIT: if you like this implementation but you do want to use it as a function, then this should do:

bool has_only_digits(const string s){
  return s.find_first_not_of( "0123456789" ) == string::npos;
}

Examples related to c++

Method Call Chaining; returning a pointer vs a reference? How can I tell if an algorithm is efficient? Difference between opening a file in binary vs text How can compare-and-swap be used for a wait-free mutual exclusion for any shared data structure? Install Qt on Ubuntu #include errors detected in vscode Cannot open include file: 'stdio.h' - Visual Studio Community 2017 - C++ Error How to fix the error "Windows SDK version 8.1" was not found? Visual Studio 2017 errors on standard headers How do I check if a Key is pressed on C++

Examples related to string

How to split a string in two and store it in a field String method cannot be found in a main class method Kotlin - How to correctly concatenate a String Replacing a character from a certain index Remove quotes from String in Python Detect whether a Python string is a number or a letter How does String substring work in Swift How does String.Index work in Swift swift 3.0 Data to String? How to parse JSON string in Typescript

Examples related to types

Cannot invoke an expression whose type lacks a call signature How to declare a Fixed length Array in TypeScript Typescript input onchange event.target.value Error: Cannot invoke an expression whose type lacks a call signature Class constructor type in typescript? What is dtype('O'), in pandas? YAML equivalent of array of objects in JSON Converting std::__cxx11::string to std::string Append a tuple to a list - what's the difference between two ways? How to check if type is Boolean

Examples related to stringstream

Qt c++ aggregate 'std::stringstream ss' has incomplete type and cannot be defined How to use stringstream to separate comma separated strings StringStream in C# Incomplete type is not allowed: stringstream How do I check if a C++ string is an int? stringstream, string, and char* conversion confusion How do I convert from stringstream to string in C++? How do you clear a stringstream variable?