views:

36741

answers:

12

I was wonding 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 compile my program under Linux, it won't even compile.

Thanks,

tomek

+19  A: 

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
Taking the Boost library for a single cast. :(
Chad Stewart
But if you're already using Boost, it's a freebie.
Chris Kaminski
+14  A: 

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);
yjerem
I was just typing that. You beat me for seconds :)
Marcel Tjandraatmadja
sprintf() isn't C++. It's C.
OJ
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
IMHO Stringstreams would be a better option.
mdec
+2  A: 

Allocate a string of sufficient length, then use snprintf.

+31  A: 

Using 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/

spoulson
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
how do you clear the stringstream?
Tomek
http://net.pku.edu.cn/~course/cs101/resource/www.cppreference.com/cppsstream/all.html
spoulson
A: 

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

Look into the use of std::stringstream.

OJ
Is C++ not a superset of C any more, then? I was under the impression that <cstdlib> and <stdlib.h> were mandated by the C++ standard ;-)
Steve Jessop
@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
Actually, to nitpick my own nitpick, C++ is only a (sort-of) superset of C89, not C99. So possibly sprintf is C++, but snprintf isn't (although compilers give you it anyway). But it's fun to say that standard features you dislike aren't really part of the standard at all. "int" is C, not C++. See?
Steve Jessop
And if that fails, you mutter darkly that they're "deprecated", point to an article by Stroustrup or Sutter explaining why they prefer not to use them, and infer that this means nobody may ever use them.
Steve Jessop
+10  A: 

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
A: 

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. http://stackoverflow.com/questions/225362/convert-a-number-to-a-string-with-specified-length-in-c#226719

Len Holgate
+8  A: 

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

paercebal
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 Kaminski
@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
@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
A: 

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
+2  A: 

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
A: 

I think that this all is too bad! I want to write my code and what I am doing the whole time is to find the best solution how to convert data types or something like that. I think all this should be done a long time ago. There must be a software engineer friendly language! There must be no need to build a new bicycle every time you write your code.

RodiQ
A: 

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