8

Hello I know it was asked many times but I hadn't found answer to my specific question.

I want to convert only string that contains only decimal numbers:

For example 256 is OK but 256a is not.

Could it be done without checking the string?

Thanks

2
  • 2
    Your subject line says "convert integer to string", but your question kind of seems to imply a string-to-int conversion... what are you trying to do?! Commented Oct 4, 2010 at 20:50
  • 1
    This post is vague and needs more punctuation. Could you explain what you mean with an example? Commented Oct 4, 2010 at 20:51

4 Answers 4

14

The simplest way that makes error checking optional that I can think of is this:

char *endptr;
int x = strtol(str, &endptr, 0);
int error = (*endptr != '\0');
Sign up to request clarification or add additional context in comments.

1 Comment

I'm not a fan of atoi since it provides no way of telling the difference between a completely invalid string and a string which is valid and converts to 0
7

In C++ way, use stringstream:

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main()
{
    stringstream sstr;
    int a = -1;

    sstr << 256 << 'a';
    sstr >> a;

    if (sstr.failbit)
    {
        cout << "Either no character was extracted, or the character can't represent a proper value." << endl;
    }
    if (sstr.badbit)
    {
        cout << "Error on stream.\n";
    }

    cout << "Extracted number " << a << endl;

    return 0;
}

2 Comments

but what if the string is not an integer? what will be the value of a ?
@Jean-FrançoisFabre: You can check stream condition by verifying the state returned by sstr.rdstate(), or by checking individual state values. I've updated my answer with the latter choice.
6

An other way using c++ style : We check the number of digits to know if the string was valid or not :

#include <iostream>
#include <sstream>
#include <string>
#include <cmath>

int main(int argc,char* argv[]) {

    std::string a("256");

    std::istringstream buffer(a);
    int number;
    buffer >> number; // OK conversion is done !
    // Let's now check if the string was valid !
    // Quick way to compute number of digits
    size_t num_of_digits = (size_t)floor( log10( abs( number ) ) ) + 1;
    if (num_of_digits!=a.length()) {
        std::cout << "Not a valid string !" << std::endl;
    }
    else {
        std::cout << "Valid conversion to " << number  << std::endl;
    }

}

1 Comment

Fails for "0", "0001", "-5".
0

In C++17 and above the best way is to use std::from_chars() from the header charconv. Unlike other solutions, this one handles overflows automatically in a neat way. It is also locale-independent, non-allocating, and non-throwing and hence the performance is expected to be better than solutions based on string streams. You may find more information in cppreference.

The following example is taken from cppreference.

#include <cassert>
#include <charconv>
#include <iomanip>
#include <iostream>
#include <string_view>
#include <system_error>
 
int main()
{
    for (std::string_view const str : {"1234", "15 foo", "bar", " 42", "5000000000"})
    {
        std::cout << "String: " << std::quoted(str) << ". ";
        int result{};
        auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), result);
 
        if (ec == std::errc())
            std::cout << "Result: " << result << ", ptr -> " << std::quoted(ptr) << '\n';
        else if (ec == std::errc::invalid_argument)
            std::cout << "This is not a number.\n";
        else if (ec == std::errc::result_out_of_range)
            std::cout << "This number is larger than an int.\n";
    }
}

Demo: https://godbolt.org/z/ohxWEbnTb

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.