While there is a set of old, C-style functions for doing this, they're limited in usefulness. There's an atoi (which converts an ASCII character to an integer), but no corresponding itoa (at least not a Standard one). With this kind of system, you'd need one function to convert each supported type to each other supported type, or at least from each supported type to some accepted intermediate type. This doesn't scale well, obviously.
C provides an alternative to these functions, sprintf and sscanf, which is a better option.
The sprintf function works like its more well-known cousin, printf, except that instead of putting its "output" on the console, it puts it into a (C-style) string, which you can then manipulate within your program. In other words, this lets you "output" an integer (or any other basic type) into a string, which subsequently contains the same string of characters that would have been output onto the console, such as a '4' followed by a '2' for the integer 42.
The sscanf function is the reverse: you use it to read values from a C-style string as if the string contained characters entered at the console for the scanf function. For example, the integer 42 would be extracted from the character '4' followed by the character '2' in a string.
These two functions are much more versatile than atoi and friends, but they still have limitations. They require that you work with C-style strings, which is never fun. Barring any implementation-specific (and therefore non-Standard) extensions to the C I/O system, sprintf and sscanf functions are also only effective for built-in types. Finally, they're not type-safe; nothing stops you from trying to output a floating point number as an octal integer if you make a typo in your format string.
The "preferred" way to do these kinds of conversions is through C++'s rich I/O system. The C++ equivalent of s{print, scan}f are the stringstreams: stringstream, istringstream, and ostringstream. (There were also some strstreams, but they're deprectated... we don't speak of them).
The general concept is the same, but stringstreams use objects of type string, which are much easier to work with than objects of type char* (C-style strings). They're also type-safe and extensible. All plusses.
An istringstream serves as input (hence the "i"). Much as you'd say "cin >> myNum;" to read an integer from the console, you can say "str_in >> myNum;" to read an integer from that istringstream's buffer (a string). To get that buffer into the stream in the first place, you call "str_in.str( the_string_with_the_integer );".
An ostringstream serves as "output." Just like writing an integer to the console with "cout << 666;" you can write an integer to an ostringstream with "str_out << 666;". To get that string out, you just call "str_out.str()", which returns the buffer.
A stringstream is a combination of {i, o}stringstream. It serves as both input and output. That means that, instead of setting its buffer as with istringstream, you can just shove something in there as if it were an ostringstream. You can then subsequently extract what that ended up as into something else. In other words, you can convert something into something else if something's output could be used as something else's input (also assuming something and something else have conventional I/O operators defined). In more other words, this is a powerful and versatile way of converting stuff to other stuff: shove stuff into a stringstream, then shove the contents of stringstream into other stuff.
Finally, we have a pretty good solution to the problem. The only bad thing about using a stringstream is that you have to use a stringstream. Every time you want to convert something, you've gotta make a new stringstream, or grab an existing one, and do your stuff. Then you have the stringstream lying around while you're not really using it anymore.
Someone out there who's still reading this just said, "Why can't you just encapsulate that process in some kind of function?" Well, you could, but you shouldn't because if you did, you'd be reinventing the wheel.
Boost (www.boost.org) has a nice tool called lexical_cast that does just that. It's a function template that you call by giving it a template argument and a regular argument. Internally, it creates a stringstream, shoves the regular argument into that, pops that out into an object whose type is that specified by the template argument, then returns that object. It also does some error checking underneath.
The end result is that you can just lexical_cast anything to anything else if their output and input are compatible, and if they have the standard operators defined.
There are also other non-Standard ways to perform these types of conversions. Many vendor-specific string classes provide member functions to convert to or from other types. The solutions described above are those that should be applicable to any Standard and reasonably recent C++ installation, and so should work anywhere (with the exception of lexical_cast, for which you'd need only a few extra (free) files from Boost).
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.