CONVERTING NUMBERS TO strings or the opposite of converting strings to numbers, is an operation that is far from as trivial as one would expect from such an obvious task – at least when it comes to C++ programming using standard libraries. The converting can be performed by the iostringstream classes in the standard library. When searching Google for the C++ way of converting between numbers and streams, the stringstream library classes appears not to be the that well known, and especially its features of the number and string operations seems generally to be unknown by many.

The stringstream offers a large range of manipulating stream data, although if used for e.g. special formatted textual output, the implementation steps tends to be somewhat more cumbersome than the old printf family.

The example below takes a few more lines that doing e.g. a atoi or snprintf kind of operation, but depending on the situation, simple conversion scenarios do not require many lines of code.

Standard Input / Output Streams Library

The main function is extracted here, just not to obfuscate the picture of the actual converting. Note that stringstream is defined in the header.

#include 
#include   // stringstream

// Prototypes
void Std_StringToInteger();
void Std_IntegerToString();

int main(int argc, char *argv[])
{
  std::cout << "Std_StringToInteger:" << std::endl;
  Std_StringToInteger();
  std::cout << "Std_IntegerToString:" << std::endl;
  Std_IntegerToString();
}

The function below handles conversion from strings to integers. First a simple conversion is done, then followed by an example of testing whether the conversion operation was a success. Last is shown how to enable exceptions on conversion errors.

void Std_StringToInteger()
{
  std::string str = "1976";
  int val;

  // Load stringstream with text to convert
  std::istringstream is(str);
  // Convert by streaming to integer
  is >> val;
  std::cout << "  Val: " << val << std::endl;

  // Clear stream for another input
  is.clear();

  // Load stream with a non numeric convertible data
  is.str("Monzool.net");
  is >> val;

  // Test if conversion failed
  if (is.fail())
    std::cout << "  Conversion failed!" << std::endl;

  // Enable exceptions on conversion errors
  try
  {
    // Set failures to be thrown as exceptions
    is.exceptions(std::istringstream::eofbit  |
                  std::istringstream::failbit |
                  std::istringstream::badbit);
  }
  catch(std::istringstream::failure& e)
  {
    std::cout << "  Exception: " << e.what() << std::endl;
    std::cout << "  Conversion failed!" << std::endl;
  }
}

As the naming stringstream indicates, input and output is done by streaming measures. If not quite confident on stream directions, think of how functions cout and cin is used. Using stringstream is no different.

Last function is for converting from numbers to strings.

void Std_IntegerToString()
{
  int val = 1976;

  // Create empty stringstream for number to convert
  std::ostringstream os("");
  // Convert by streaming integer
  os << val;
  std::cout << "  Str: " <<  os.str() << std::endl;
}

Boost lexical_cast

To put it simple: when dealing with libraries for converting between numbers and strings the Boost library smokes the standard C++ library ditto.

The conversion features of Boost is located in the lexical_cast library and is embedded by including the lexical_cast.hpp file (most Boost libraries are implemented in header files and can be embedded by including the appropriate hpp file.).

#include 
#include 

// Prototypes
void Boost_StringToInteger();
void Boost_IntegerToString();

int main(int argc, char *argv[])
{
  std::cout << "Boost_StringToInteger:" << std::endl;
  Boost_StringToInteger();
  std::cout << "Boost_IntegerToString:" << std::endl;
  Boost_IntegerToString();
}

Instead of using streaming functionality, Boost has chosen a much more obvious concept. Boost has added the functionality of simply casting between numbers and strings. Casting functions are already a familiar concept in C++, like casting between data types using static_cast or manipulating const'ness with const_cast.

The lexical_cast template function makes converting from string to integer trivial. The example below also shows how to handle conversion errors by exception handling.

void Boost_StringToInteger()
{
  std::string str = "1976";
  // Cast string to integer
  int val = boost::lexical_cast(str);
  std::cout << "  Val: " << val << std::endl;

  // Load string with non numeric convertible data
  str = "Monzool.net";
  try
  {
    // Non convertible values throws exceptions
    val = boost::lexical_cast(str);
  }
  catch (boost::bad_lexical_cast &e)
  {
    std::cout << "  Exception: " << e.what() << std::endl;
    std::cout << "  Conversion failed!" << std::endl;
  }
}

Converting the other way from integer to string is just as trivial.

void Boost_IntegerToString()
{
  int val = 1976;
  // Cast integer to string
  std::string str = boost::lexical_cast(val);
  std::cout << "  Str: " << str << std::endl;
}

When it comes to simple conversion between numbers and strings, Boost is far superior in simplicity. However note that the design goals have also been very different for the two libraries. The C++ Standard Input/Output Streams Library has been designed for flexibility. And flexible it is indeed, but sadly this side effects to complicating its usage even for obvious tasks that ought to be trivial to perform.