10

Disclaimer: Links are to cppreference.com

So I have known for a while that std::atoi has been deprecated and it's been recommended to use std::strtol instead.

C++11 has introduced std::stoi and I'm trying to understand why one would choose to use it over std::strtol.

From what I understand is that stoi calls strtol but throws exceptions. Also it returns an integer instead of a long.

Are these the main differences, what am I missing?

jmstoker
  • 3,315
  • 22
  • 36
  • possible duplicate of [Why is there no std::stou?](http://stackoverflow.com/questions/8715213/why-is-there-no-stdstou) – Kerrek SB Oct 08 '13 at 22:49
  • @KerrekSB That's really an unrelated question... – Reed Copsey Oct 08 '13 at 22:53
  • @KerrekSB my question is to better understand why to use stoi if ultimately it just calls strtol. – jmstoker Oct 08 '13 at 23:03
  • 1
    `std::atoi` has not been deprecated. Deprecation is done in the C++ Standard to indicate that something may be going away in the future. Some people don't approve of `atoi`; that's not deprecation. – Pete Becker Oct 08 '13 at 23:41
  • Taken from the [FreeBSD man page of atoi](http://www.manpagez.com/man/3/atoi/): `The atoi() function has been deprecated by strtol() and should not be used in new code.` This may only apply to FreeBSD, but in the portability sense, that would lean me towards not using it in production code. – jmstoker Oct 09 '13 at 00:02
  • 1
    @jmstoker The Linux man page for atoi does not mention any deprecation. But since atoi() does not detect errors, I would definitely /not/ use it in production code! – Torkel Bjørnson-Langen Feb 07 '14 at 16:02

6 Answers6

10

Are these the main differences, what am I missing?

The newer, std::stoi also works directly from std::string (so you don't have to litter your code with .c_str() calls) and optionally provides you the first unmatched character as an index via a size_t, rather than as a pointer.

These changes simplify the usage from within your code.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • So is it safe to assume that stoi provides convenience at the expense of some overhead due to internal casting to convert the string and return an int? – jmstoker Oct 08 '13 at 23:11
  • @jmstoker I suspect you're not going to be getting much overhead, though, as you'd have to do the same conversions if you're using `std::string` as input. – Reed Copsey Oct 08 '13 at 23:14
  • Right, I'm just wondering if there is more going on in stoi, like the logic providing the exceptions. I'm probably over analyzing it, but it has me intrigued. – jmstoker Oct 08 '13 at 23:18
  • @jmstoker I suspect the exception logic is more of just a format check on the result of `std::strtol`, since it returns error codes instead of exceptions. On success, it's likely very low overhead. – Reed Copsey Oct 08 '13 at 23:24
  • Conversely, if you have string data that is not stored in `std::string` (perhaps it's a memory-mapped text file), then usage of `strtol` is much simpler. – Ben Voigt Jul 05 '14 at 20:56
2

One big difference is that stoi takes an std::string as its argument, so you don't have to tack .c_str() onto a string to convert it to an integer.

If you want to convert to a long, you can use stol instead (and likewise, stod, stof stold, stoul, stoll to convert to double, float, long double, unsigned long, and long long respectively).

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
2

You'd use std::stoi() if you want to pass a std::basic_string and you want to get out an int. If you prefer to get out a long you'd call std::stol().

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
2

I prefer stoi() over strtol() since the former throws std::invalid_argument on invalid input. To bad the exception message in GNUs libstdc++ is not to helpfull. E.g.: "what(): stoi"

0

std:stoi is not C compatible and is packed with <string> library which has other object oriented implementations that cannot be compiled by a C compiler. Its main use case scenario (should) involves with std:string instead of byte arrays to comply with modern C++ common practice.

diegoperini
  • 1,796
  • 21
  • 37
-2

Actually, I really wonder why there is not a std::FromString template function taking the type to which you want the string converted as a template parameter. Likewise a ToString template function doing the reverse.

You can easily imagine the implementation using insertion and extraction operators.

int i = std::FromString <int> (std::string ("2"))
int j = std::FromString <int> ("2")

std::string = ToString <double> (3.14159)

Yes, of course the function names would not have capital letters and they would likely be from_string and to_string .

Template specialization is possible, of course. Finally, there really is no restrictions that the types would have to be native types, right?

Fred Mitchell
  • 2,145
  • 2
  • 21
  • 29
  • True. It "does not answer the question". But creating the two templates is so easy, that I actually think that the resulting codebase will be far more readable and easier to use. (Yes, I have written them. They are truly simple exercises in template functions. Unfortunately, because I wrote them as part of work product, I may not reproduce the code here.) – Fred Mitchell Oct 08 '13 at 23:29
  • 2
    I'm not arguing their usefulness. Boost already has `lexical_cast` anyway. I'm just saying your answer doesn't belong here. Maybe it belongs on your blog, or in answer to a question that asked for a third way of converting types, rather that for a comparison of two others that this answer completely ignores. – Rob Kennedy Oct 09 '13 at 02:54