151

I was wondering if there was an alternative to itoa() for converting an integer to a string because when I run it in visual Studio I get warnings, and when I try to build my program under Linux, I get a compilation error.

tshepang
  • 10,772
  • 21
  • 84
  • 127
Tomek
  • 4,527
  • 14
  • 40
  • 48
  • Basically the inverse of this question. http://stackoverflow.com/questions/200090/how-do-you-convert-a-c-string-to-an-int Answer is the same though. – Martin York Oct 23 '08 at 03:48
  • 16
    How about some of the examples from the following: http://www.codeproject.com/KB/recipes/Tokenizer.aspx They are very efficient and somewhat elegant. –  Nov 02 '10 at 04:59
  • 1
    You can see [here](http://stackoverflow.com/q/23437778/2567683) a benchmark comparing 3 modern C+ ways of converting integers to strings – Nikos Athanasiou May 11 '14 at 08:13
  • I had the same requirement for a function in C. I'm sure you can figure out how to wrap in in C++. It is thread-safe and handles all positive, negative 32 bit integer numbers, and zero. The performance is EXCELLENT, and the algorithm is lean, so it doesn't soak up a lot of cache. Ben Voigt has a faster approach, but it's not a lightweight algorithm, so unless you are doing billions of these things, it maybe overkill. –  Jul 01 '14 at 07:51

18 Answers18

186

In C++11 you can use std::to_string:

#include <string>

std::string s = std::to_string(5);

If you're working with prior to C++11, you could use C++ streams:

#include <sstream>

int i = 5;
std::string s;
std::stringstream out;
out << i;
s = out.str();

Taken from http://notfaq.wordpress.com/2006/08/30/c-convert-int-to-string/

bobobobo
  • 57,855
  • 58
  • 238
  • 337
spoulson
  • 20,523
  • 14
  • 72
  • 101
  • 1
    Too bad Windows CE derived platforms doesn't have iostreams by default. The way to go there is preferaby with the _itoa<> family. – Johann Gerell Oct 23 '08 at 17:31
  • 1
    how do you clear the stringstream? – Tomek Oct 23 '08 at 19:31
  • http://net.pku.edu.cn/~course/cs101/resource/www.cppreference.com/cppsstream/all.html – spoulson Oct 24 '08 at 17:30
  • I suppose you mean: http://www.cppreference.com/cppsstream/all.html – Wodin Dec 15 '10 at 09:07
  • stringstream is nice but be aware that it can *dramatically* increase the size of the executable. – Jay Jan 31 '13 at 16:48
  • (for non C++11) There is also `boost::to_string` http://www.boost.org/doc/libs/1_51_0/boost/exception/to_string.hpp – alfC Jul 09 '13 at 06:21
  • @Jay You can see [here](http://stackoverflow.com/q/23437778/2567683) a benchmark comparing 3 modern C+ ways of converting integers to strings and in one the answers common mistakes related to the use of stringstream – Nikos Athanasiou May 11 '14 at 08:16
  • @NikosAthanasiou Excellent reference, thanks. It doesn't mention the size of the executable generated. I've seen gcc add megabytes of unused code to the executable. – Jay May 11 '14 at 13:19
56

boost::lexical_cast works pretty well.

#include <boost/lexical_cast.hpp>
int main(int argc, char** argv) {
    std::string foo = boost::lexical_cast<std::string>(argc);
}
Leon Timmermans
  • 29,284
  • 2
  • 59
  • 110
  • 25
    Taking the Boost library for a single cast. :( – Chad Stewart Jan 13 '10 at 20:29
  • 22
    But if you're already using Boost, it's a freebie. – Chris K May 30 '10 at 13:50
  • 12
    boost::lexical_cast is painfully slow. Do not use it if performance is important. –  Nov 02 '10 at 05:02
  • 10
    I think worrying about that is premature optimization in most cases. It wouldn't stop me from using it unless my profiler told me otherwise. – Leon Timmermans Nov 04 '10 at 18:22
  • 15
    Painfully slow? Where did you get that? It actually performs rather well! http://www.boost.org/doc/libs/1_49_0/doc/html/boost_lexical_cast/performance.html – kralyk Apr 27 '12 at 23:34
  • 1
    @kralyk To clarify, [lexical_cast is claimed to __outperform__ both `sprintf` and `stringstream` by a lot](http://www.boost.org/doc/libs/1_47_0/libs/conversion/lexical_cast.htm) (scroll to bottom), except for `string->float` and `float->string`, where `sprintf` is the winner. – bobobobo May 07 '13 at 20:47
  • @bobobobo You can see [here](http://stackoverflow.com/q/23437778/2567683) a benchmark comparing 3 modern C+ ways of converting integers to strings and the actual performance of lexical cast – Nikos Athanasiou May 11 '14 at 08:17
50

Archeology

itoa was a non-standard helper function designed to complement the atoi standard function, and probably hiding a sprintf (Most its features can be implemented in terms of sprintf): http://www.cplusplus.com/reference/clibrary/cstdlib/itoa.html

The C Way

Use sprintf. Or snprintf. Or whatever tool you find.

Despite the fact some functions are not in the standard, as rightly mentioned by "onebyone" in one of his comments, most compiler will offer you an alternative (e.g. Visual C++ has its own _snprintf you can typedef to snprintf if you need it).

The C++ way.

Use the C++ streams (in the current case std::stringstream (or even the deprecated std::strstream, as proposed by Herb Sutter in one of his books, because it's somewhat faster).

Conclusion

You're in C++, which means that you can choose the way you want it:

  • The faster way (i.e. the C way), but you should be sure the code is a bottleneck in your application (premature optimizations are evil, etc.) and that your code is safely encapsulated to avoid risking buffer overruns.

  • The safer way (i.e., the C++ way), if you know this part of the code is not critical, so better be sure this part of the code won't break at random moments because someone mistook a size or a pointer (which happens in real life, like... yesterday, on my computer, because someone thought it "cool" to use the faster way without really needing it).

Community
  • 1
  • 1
paercebal
  • 75,594
  • 37
  • 124
  • 157
  • The C way isn't necessarily faster - remember *printf() and family have to implement their own runtime lexical engine to parse your input string - the C++ version doesn't have this limitation. – Chris K May 30 '10 at 13:52
  • 3
    @Chris Kaminski: My one tests did show the sprintf was a 5 to ten times faster, which is confirmed my Herb Sutter's own measurements. if you have tests with different results, I'm interested. – paercebal May 31 '10 at 09:08
  • 3
    @Chris Kaminski: If you study the c++ stream's interface, you'll understand why they are slower, even when output a simple integer: In C, you use your own buffer, possibly allocated in the stack, whereas in C++, the stringstream will use its own. In C, you can then reuse your buffer. In C++, you must extract the string from the stringstream, which is a std::string copy. – paercebal May 31 '10 at 09:10
  • If you need fast int-to-string, you can write a quick function that's faster than any generic library call; just keep taking %10 and /10, and fill a static buffer from the back, returning a pointer to the highest digit. Don't use sprintf, this is a security flaw. – fuzzyTew Sep 06 '11 at 02:44
  • @fuzzyTew : Do you have performance comparison between a generic sprintf and your quick function? – paercebal Sep 06 '11 at 10:24
  • @paercebal: A performance comparison is going to differ widely depending on platform and library version, but you can see at http://sourceware.org/git/?p=glibc.git;a=blob;f=stdio-common/_itoa.c#l189 that in glibc at least, the itoa function (which is called by sprintf) _is_ my quick function; the difference is that it is nested inside a number of unnecessary jump tables to handle bases and string formatting, and is hidden behind an uninlineable library call. It usually gives better results to make your own optimized functions if you need fast specific tasks. – fuzzyTew Sep 06 '11 at 21:29
  • @fuzzyTew : Ok. Interesting to know, and a good exercise for a coder, but as far as I am concerned *(following the "premature optimization is the root of all evil" principle)*, most of the time *(i.e. 99% of the time)*, a one-line `sprintf(buffer, "%i")` safely wrapped in a function or object will be more than enough if performance is an issue forbidding the use of the iostreams, and less as source of bugs than a fully hand-coded function. – paercebal Sep 06 '11 at 22:03
  • @paercebal: I can see that. You should really never use `sprintf` -- if your code is ever used on a system where the width of an integer allows values outside the size of your buffer (or you forget to allow for a negative sign or the trailing `\0` or misguess the number of base ten digits available), you will have crashes and potential security problems. `snprintf` and `itoa` are safer and comparable in speed (`itoa` should be faster with modern gcc). The C++ standard library now includes the `to_string` optimized template functions anyway, which resolve all this craziness once and for all. – fuzzyTew Sep 07 '11 at 04:41
  • 2
    @fuzzyTew : Thanks for your concern, but I guess I'm familiar enough with both C API and C++ API to handle sprintf, and know when (and how) to use it safely, and when NOT to use it at all... :-D – paercebal Sep 07 '11 at 10:52
  • @paercebal: But why get in the habit of using sprintf, which will probably emit a warning on secure systems even if used safely, when snprintf is available? How can you know that a standard library will convert values to strings of a given length in any possible system your code will be compiled on? In glibc, a user of code you write may have redefined a format specifier: http://www.gnu.org/software/libc/manual/html_node/Registering-New-Conversions.html ! It is impossible to know for sure how much data sprintf will write except in a restricted environment. Don't use it in production code. – fuzzyTew Sep 07 '11 at 15:28
  • 2
    @fuzzyTew: `1` In my post, I spoke about sprintf and its secure variants, not only sprintf. `2` Knowing where your code is compiled is not an impossible task (in my case, at worst, Windows/VC++, Solaris/CC and Linux/g++, at best, Windows/VC++ only). `3` You are describing a world where saboteurs trying to crash your code are the norm. My world is composed by normal developers, so losing time trying to protect my code from saboteurs by rewriting my "secure" version of every API is not productive. [...] – paercebal Sep 08 '11 at 11:06
  • 2
    @fuzzyTew: [...] `Conclusion` Use the best tool at hand. And if the best tool is a sprintf hidden inside a wrapper class or function... Now, if you advocate the rewriting of sprintf as an answer for this question, feel free to write your own answer. I'm not sure the question author reads all the comments. – paercebal Sep 08 '11 at 11:07
  • You can see [here](http://stackoverflow.com/q/23437778/2567683) a benchmark comparing 3 modern C+ ways of converting integers to strings – Nikos Athanasiou May 11 '14 at 08:18
  • sprintf is also pretty slow compared to a proper itoa implementation. – Erik Aronesty Jul 07 '14 at 20:45
  • This solves most data->string issues in a reusable manner: http://stackoverflow.com/questions/2342162/stdstring-formatting-like-sprintf – Erik Aronesty Mar 26 '15 at 13:55
35

Try sprintf():

char str[12];
int num = 3;
sprintf(str, "%d", num); // str now contains "3"

sprintf() is like printf() but outputs to a string.

Also, as Parappa mentioned in the comments, you might want to use snprintf() to stop a buffer overflow from occuring (where the number you're converting doesn't fit the size of your string.) It works like this:

snprintf(str, sizeof(str), "%d", num);
Paige Ruten
  • 157,734
  • 36
  • 172
  • 191
  • 8
    sprintf() isn't C++. It's C. – OJ. Oct 23 '08 at 00:30
  • 11
    You should use snprintf() to avoid buffer overflows. It's only a one line change in the above example: snprintf(str, sizeof(str), "%d", num); – Parappa Oct 23 '08 at 00:33
  • 2
    IMHO Stringstreams would be a better option. – mdec Oct 23 '08 at 00:45
  • 2
    OJ: sprintf is c++ too... most C stuff works in c++. this is not an accident. c++ was intended to be a "layer" on top of c++... not a defining architecture like it's (probably to a fault) become – Erik Aronesty Jul 07 '14 at 20:46
  • The type of str in function: sprintf is 'str', but question should be 'string'. – Xb74Dkjb Dec 07 '15 at 17:35
20

Behind the scenes, lexical_cast does this:

std::stringstream str;
str << myint;
std::string result;
str >> result;

If you don't want to "drag in" boost for this, then using the above is a good solution.

1800 INFORMATION
  • 119,313
  • 29
  • 152
  • 234
12

We can define our own iota function in c++ as:

string itoa(int a)
{
    string ss="";   //create empty string
    while(a)
    {
        int x=a%10;
        a/=10;
        char i='0';
        i=i+x;
        ss=i+ss;      //append new character at the front of the string!
    }
    return ss;
}

Don't forget to #include <string>.

Tag318
  • 162
  • 1
  • 5
11

С++11 finally resolves this providing std::to_string. Also boost::lexical_cast is handy tool for older compilers.

Patryk
  • 18,244
  • 37
  • 110
  • 212
Vasaka
  • 1,833
  • 1
  • 18
  • 30
9

I use these templates

template <typename T> string toStr(T tmp)
{
    ostringstream out;
    out << tmp;
    return out.str();
}


template <typename T> T strTo(string tmp)
{
    T output;
    istringstream in(tmp);
    in >> output;
    return output;
}
jm1234567890
  • 1,452
  • 2
  • 18
  • 29
7

Try Boost.Format or FastFormat, both high-quality C++ libraries:

int i = 10;
std::string result;

WIth Boost.Format

result = str(boost::format("%1%", i));

or FastFormat

fastformat::fmt(result, "{0}", i);
fastformat::write(result, i);

Obviously they both do a lot more than a simple conversion of a single integer

dcw
  • 3,371
  • 2
  • 20
  • 30
6

You can actually convert anything to a string with one cleverly written template function. This code example uses a loop to create subdirectories in a Win-32 system. The string concatenation operator, operator+, is used to concatenate a root with a suffix to generate directory names. The suffix is created by converting the loop control variable, i, to a C++ string, using the template function, and concatenating that with another string.

//Mark Renslow, Globe University, Minnesota School of Business, Utah Career College
//C++ instructor and Network Dean of Information Technology

#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream> // string stream
#include <direct.h>

using namespace std;

string intToString(int x)
{
/**************************************/
/* This function is similar to itoa() */
/* "integer to alpha", a non-standard */
/* C language function. It takes an   */
/* integer as input and as output,    */
/* returns a C++ string.              */
/* itoa()  returned a C-string (null- */
/* terminated)                        */
/* This function is not needed because*/
/* the following template function    */
/* does it all                        */
/**************************************/   
       string r;
       stringstream s;

       s << x;
       r = s.str();

       return r;

}

template <class T>
string toString( T argument)
{
/**************************************/
/* This template shows the power of   */
/* C++ templates. This function will  */
/* convert anything to a string!      */
/* Precondition:                      */
/* operator<< is defined for type T    */
/**************************************/
       string r;
       stringstream s;

       s << argument;
       r = s.str();

       return r;

}

int main( )
{
    string s;

    cout << "What directory would you like me to make?";

    cin >> s;

    try
    {
      mkdir(s.c_str());
    }
    catch (exception& e) 
    {
      cerr << e.what( ) << endl;
    }

    chdir(s.c_str());

    //Using a loop and string concatenation to make several sub-directories
    for(int i = 0; i < 10; i++)
    {
        s = "Dir_";
        s = s + toString(i);
        mkdir(s.c_str());
    }
    system("PAUSE");
    return EXIT_SUCCESS;
}
Mark Renslow
  • 61
  • 1
  • 1
4

Allocate a string of sufficient length, then use snprintf.

Iain
  • 4,103
  • 21
  • 21
2

If you are interested in fast as well as safe integer to string conversion method and not limited to the standard library, I can recommend the format_int method from the {fmt} library:

fmt::format_int(42).str();   // convert to std::string
fmt::format_int(42).c_str(); // convert and get as a C string
                             // (mind the lifetime, same as std::string::c_str())

According to the integer to string conversion benchmarks from Boost Karma, this method several times faster than glibc's sprintf or std::stringstream. It is even faster than Boost Karma's own int_generator as was confirm by an independent benchmark.

Disclaimer: I'm the author of this library.

vitaut
  • 37,224
  • 19
  • 144
  • 248
2

I wrote this thread-safe function some time ago, and am very happy with the results and feel the algorithm is lightweight and lean, with performance that is about 3X the standard MSVC _itoa() function.

Here's the link. Optimal Base-10 only itoa() function? Performance is at least 10X that of sprintf(). The benchmark is also the function's QA test, as follows.

start = clock();
for (int i = LONG_MIN; i < LONG_MAX; i++) {
    if (i != atoi(_i32toa(buff, (int32_t)i))) {
        printf("\nError for %i", i);
    }
    if (!i) printf("\nAt zero");
}
printf("\nElapsed time was %f milliseconds", (double)clock() - (double)(start));

There are some silly suggestions made about using the caller's storage that would leave the result floating somewhere in a buffer in the caller's address space. Ignore them. The code I listed works perfectly, as the benchmark/QA code demonstrates.

I believe this code is lean enough to use in an embedded environment. YMMV, of course.

Community
  • 1
  • 1
2

The best answer, IMO, is the function provided here:

http://www.jb.man.ac.uk/~slowe/cpp/itoa.html

It mimics the non-ANSI function provided by many libs.

char* itoa(int value, char* result, int base);

It's also lightning fast and optimizes well under -O3, and the reason you're not using c++ string_format() ... or sprintf is that they are too slow, right?

Erik Aronesty
  • 8,927
  • 4
  • 46
  • 29
  • 2
    This is the only answer that fully answers the question. The C++ `to_string()` method does not replicate the full functionality of C's `itoa` as it cannot deal with arbitrary bases. A little confusing why this functionality wouldn't have been included, especially considering that the inverse function `stoi()` can handle arbitrary bases. – Daniel Oct 16 '14 at 12:35
  • 2
    Updated link (same article): http://www.strudel.org.uk/itoa/ – nloveladyallen Feb 12 '17 at 20:36
2
int number = 123;

stringstream = s;

s << number;

cout << ss.str() << endl;
RyanR
  • 7,662
  • 1
  • 22
  • 39
Kendra
  • 21
  • 1
1

Note that all of the stringstream methods may involve locking around the use of the locale object for formatting. This may be something to be wary of if you're using this conversion from multiple threads...

See here for more. Convert a number to a string with specified length in C++

Community
  • 1
  • 1
Len Holgate
  • 20,256
  • 4
  • 40
  • 89
0

On Windows CE derived platforms, there are no iostreams by default. The way to go there is preferaby with the _itoa<> family, usually _itow<> (since most string stuff are Unicode there anyway).

Johann Gerell
  • 23,388
  • 8
  • 64
  • 118
-1

Most of the above suggestions technically aren't C++, they're C solutions.

Look into the use of std::stringstream.

OJ.
  • 27,508
  • 5
  • 52
  • 69
  • 1
    @OJ: "technically aren't C++" - That's nitpicking (and to nitpick further, as onebyone mentions most of them are technically in C++), especially since the OP was looking for a no-warning replacement for itoa(). – Michael Burr Oct 23 '08 at 02:07