Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check std::string if its indeed an integer?

The following code converts an std::string to int and the problem lies with the fact that it cannot discern from a true integer or just a random string. Is there a systematic method for dealing with such a problem?

#include <cstring>
#include <iostream>
#include <sstream>

int main()
{
    std::string str =  "H";

    int int_value;
    std::istringstream ss(str);
    ss >> int_value;

    std::cout<<int_value<<std::endl;

    return 0;
}

EDIT: This is the solution that I liked because it is very minimal and elegant! It doesn't work for negative numbers but I only needed positive ones anyways.

#include <cstring>
#include <iostream>
#include <sstream>

int main()
{
    std::string str =  "2147483647";

    int int_value;
    std::istringstream ss(str);

    if (ss >> int_value)
        std::cout << "Hooray!" << std::endl;

    std::cout<<int_value<<std::endl;


    str =  "-2147483648";
    std::istringstream negative_ss(str);

    if (ss >> int_value)
        std::cout << "Hooray!" << std::endl;

    std::cout<<int_value<<std::endl;

    return 0;
}
like image 271
pandoragami Avatar asked Apr 24 '13 00:04

pandoragami


People also ask

How do you check if a string is an integer C++?

Using built-in method isdigit(), each character of string is checked. If the string character is a number, it will print that string contains int. If string contains character or alphabet, it will print that string does not contain int.

How do you check if a char is a number C++?

The function isdigit() is used to check that character is a numeric character or not. This function is declared in “ctype. h” header file. It returns an integer value, if the argument is a digit otherwise, it returns zero.

How do you check if a string begins with a string C++?

The string class in C++ has a member function called start_with(). It checks if a sub-independent string, forms the first characters of a string of interest (prefix). The overloaded member functions are starts_with(charT x), starts_with(const charT* x), and starts_with(string_view x). Each returns a bool.


2 Answers

You may try to use Boost lexical_cast, it will throw an exception if the cast failed.

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

EDIT Accorinding to @chris, You may also try to use std::stoi since C++11. It will throw std::invalid_argument exception if no conversion could be performed. You may find more information here: std::stoi

like image 68
taocp Avatar answered Sep 27 '22 23:09

taocp


WhozCraig's approach is much nicer and I wanted to expand on it using the approach that the C++ FAQ uses which is as follows:

#include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>

class BadConversion : public std::runtime_error {
public:
  BadConversion(std::string const& s)
    : std::runtime_error(s)
    { }
};



inline int convertToInt(std::string const& s,
                              bool failIfLeftoverChars = true)
{
  std::istringstream i(s);
  int x;
  char c;
  if (!(i >> x) || (failIfLeftoverChars && i.get(c)))
    throw BadConversion("convertToInt(\"" + s + "\")");
  return x;
}


int main()
{
    std::cout << convertToInt( "100" ) << std::endl ;
    std::cout << convertToInt( "-100" ) << std::endl ;
    std::cout << convertToInt( "  -100" ) << std::endl ;
    std::cout << convertToInt( "  -100  ", false ) << std::endl ;

    // The next two will fail
    std::cout << convertToInt( "  -100  ", true ) << std::endl ;
    std::cout << convertToInt( "H" ) << std::endl ;
}

This is robust and will know if the conversion fails, you also can optionally choose to fail on left over characters.

like image 28
Shafik Yaghmour Avatar answered Sep 27 '22 23:09

Shafik Yaghmour