5

I'm seeing a lot of options for converting a string to a number in C++.

Some of which are actually recommending the use of standard C functions such as atoi and atof.

I have not seen anyone suggesting the following option, which relies solely on C++ STL:

int Str2Num(const string& str) // can be called with a 'char*' argument as well
{
    int num;
    istringstream(str)>>num;
    return num;
}

Or more generally:

template <typename type>
type Str2Num(const string& str) // can be called with a 'char*' argument as well
{
    type num;
    istringstream(str)>>num;
    return num;
}

What are the disadvantages in the above implementation?

Is there a simpler / cleaner way to achieve this conversion?

barak manos
  • 29,648
  • 10
  • 62
  • 114
  • 3
    If this is not a duplicate I would be deeply surprised. – user2672165 Mar 01 '14 at 12:30
  • Have a look at `boost::lexical_cast`: http://www.boost.org/doc/libs/1_55_0/doc/html/boost_lexical_cast.html – Messa Mar 01 '14 at 12:34
  • @user2672165, here is the first sentence in my question: "I'm seeing a lot of options for converting a string to a number in C++". And here is the third sentence in my question: "I have not seen anyone suggesting the following option, which relies solely on C++ STL". So obviously, I have posted this question after not being able to find an answer which fits the "pure C++ STL" requirements. – barak manos Mar 01 '14 at 12:41
  • possible duplicate of [How to parse a string to an int in C++?](http://stackoverflow.com/questions/194465/how-to-parse-a-string-to-an-int-in-c) – Ali Mar 01 '14 at 12:42
  • @Ali, hi. Please read my comment to user2672165 above. – barak manos Mar 01 '14 at 12:45
  • @barakmanos If you look at that question I linked, you will see that [the most upvoted answer](http://stackoverflow.com/a/6154614/341970) discusses (basically) your code snippets first and tells you why they are flawed and what to use instead. – Ali Mar 01 '14 at 12:49
  • @Ali, thanks. The 'What not to do' part is good, because it refers directly to my code snippet and answers my question about the disadvantages in this implementation. The 'The best solution' part actually "falls back" to the use of standard C functions, which in my question, I am (implicitly) hoping to avoid. – barak manos Mar 01 '14 at 12:55
  • @barakmanos If efficiency is not a major concern, then there is no problem with `std::stoi()` and friends. Nevertheless, I think it is good to know your alternatives, even if you decide to use `std::stoi()` in the end. – Ali Mar 01 '14 at 12:58
  • @Ali: thanks very much. I agree about knowing the alternatives. Efficiency is not the issue in this case, as I was merely looking for the simplest and cleanest way to achieve this conversion. "`std::stoi()` and friends" where suggested here in one of the answers below, and they're exactly what I was aiming for. I didn't see this option in any of the related posts that I have visited. – barak manos Mar 01 '14 at 13:05
  • @barakmanos Well, [it is the accepted answer](http://stackoverflow.com/a/11354496/341970) of the above linked question. Let's leave it at that. – Ali Mar 01 '14 at 13:17
  • @barak: The best reason why you should avoid atoi() et al wasn't even stated yet. You cannot check errors with them; they return 0 if they cannot parse the input, so you cannot distinguish between, say "0" and "xxx". std::stoi() and the other new functions fix this defect and throw an exception if the input is invalid. – Christian Hackl Mar 01 '14 at 15:43
  • @Christian Hackl: nowhere within the question did I express my desire to use `atoi`. If anything, I pretty much stated the opposite (though I didn't do so explicitly). – barak manos Mar 01 '14 at 15:58
  • @barak: I know. I thought it was interesting for others reading the question and answers. – Christian Hackl Mar 01 '14 at 16:02
  • @Christian Hackl: OK, I understand now. It was my assumption to begin with, and the main reason for asking this question (otherwise I would have just used `atoi` and `atof`). Thank you for the info :) – barak manos Mar 01 '14 at 16:11

4 Answers4

8

Since C++11, we have had std::stoi:

std::stoi(str)

There is also std::stol and std::stoll.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • Great!!! That's what I was looking for when I said "Is there a simpler / cleaner way to achieve this conversion?"... `stod` for `double`? – barak manos Mar 01 '14 at 12:45
  • @barakmanos Yeah, there are [floating point alternatives](http://en.cppreference.com/w/cpp/string/basic_string/stof) too. – Joseph Mansfield Mar 01 '14 at 12:53
3

In there's a number of numeric conversion functions defined in the std::string class itself:

Numeric conversions
stoi (C++11)
stol (C++11)
stoll (C++11)

converts a string to a signed integer

stoul (C++11)
stoull (C++11)

converts a string to an unsigned integer

stof (C++11)
stod (C++11)
stold (C++11)

converts a string to a floating point value

As for pre c++11 standards, I can't see any disadvantages from your template function sample.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
1

#include <iostream>
#include <string>

int main() {

    std::string str = "123";
    int num;

    // using stoi() to store the value of str1 to x
    num = std::stoi(str);

    std::cout << num;

    return 0;
}
0
#include <sstream>
template <typename T>
inline bool StringToNumber(const std::string& sString, T &tX)
{
    std::istringstream iStream(sString);
    return !(iStream >> tX).fail();not
}

Then call

double num{};
StringToNumber(std::string{"580.8"}, num);

float fnum{};
StringToNumber(std::string{"5e+1.0"}, fnum);
Yi Yu
  • 1
  • 1
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 01 '22 at 07:18
  • How this answers the question asked by OP? – Abhishek Dutt Jul 01 '22 at 07:21
  • what does `not` in ` return !(iStream >> tX).fail();not`? – kyb Aug 26 '23 at 22:20