165

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.

4
  • Basically the inverse of this question. stackoverflow.com/questions/200090/… Answer is the same though. Commented Oct 23, 2008 at 3:48
  • 16
    How about some of the examples from the following: codeproject.com/KB/recipes/Tokenizer.aspx They are very efficient and somewhat elegant. Commented Nov 2, 2010 at 4:59
  • 1
    You can see here a benchmark comparing 3 modern C+ ways of converting integers to strings Commented May 11, 2014 at 8: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. Commented Jul 1, 2014 at 7:51

18 Answers 18

202

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/

Sign up to request clarification or add additional context in comments.

8 Comments

Too bad Windows CE derived platforms doesn't have iostreams by default. The way to go there is preferaby with the _itoa<> family.
how do you clear the stringstream?
stringstream is nice but be aware that it can dramatically increase the size of the executable.
|
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);
}

7 Comments

Taking the Boost library for a single cast. :(
But if you're already using Boost, it's a freebie.
boost::lexical_cast is painfully slow. Do not use it if performance is important.
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.
Painfully slow? Where did you get that? It actually performs rather well! boost.org/doc/libs/1_49_0/doc/html/boost_lexical_cast/…
|
51

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).

15 Comments

@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.
@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.
@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
@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. [...]
@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.
|
39

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);

5 Comments

sprintf() isn't C++. It's C.
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);
IMHO Stringstreams would be a better option.
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
The type of str in function: sprintf is 'str', but question should be 'string'.
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.

3 Comments

I doubt it would stream into the string when str.str() would suffice.
if lexical_cast does this, how is the big gap in performance explained?
Didn't he explain that in the question you linked as being due to creating stringstream objects every time?
13

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

Comments

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>.

1 Comment

This algorithm will produce an empty string if a is 0. Change the while loop to a do-while loop.
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;
}

1 Comment

These are good but unfortunately lack error handling.
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

Comments

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;
}

Comments

4

Allocate a string of sufficient length, then use snprintf.

Comments

2
int number = 123;

stringstream = s;

s << number;

cout << ss.str() << endl;

Comments

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.

Comments

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?

2 Comments

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.
Updated link (same article): strudel.org.uk/itoa
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.

Comments

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++

Comments

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).

Comments

-1

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

Look into the use of std::stringstream.

1 Comment

@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().

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.