These articles are written by Codalogic empowerees as a way of sharing knowledge with the programming community. They do not necessarily reflect the opinions of Codalogic.

Cheap and Cheerful Formatting with std::to_string()

By: Pete, August 2016

Occasioinally you may want to create a string that contains numbers. You could use an std::ostringstream or sprintf() but the former is quite heavy handed and the latter has to worry about buffer overflow.

A cheap and cheerful solution is to use std::string and std::to_string().

Let's imagine that we have a widget (represented here by fake_widget()) that we want to send string values to for display to the user. These will be made up of some fixed text and some variable text.

For example, if we had a string based file name in a variable we could do:

    fake_widget( std::string( "Can't open file: " ).append( file_name ) );

On the other hand, if we need to display the user a number, we can use std::to_string() as follows:

    fake_widget( std::string( "Volume = " ).append( std::to_string( volume ) ) );

We can display longer message fragments but it will become cumbersome and possibly inefficent compared to other options. For example:

    fake_widget( std::string( "You have " )
                    .append( std::to_string( n_errors ) )
                    .append( " errors in " )
                    .append( std::to_string( n_files ) )
                    .append( " files." ) );

The full example program is:

#include <iostream>
#include <string>

void fake_widget( const std::string & s )
{
    std::cout << s << "\n";
}

// Pretend these are set earlier in the application
std::string file_name{ "notes.txt" };
int volume = 6;
int n_errors = 8;
int n_files = 4;

int main()
{
    // Combining a fixed string and a dynamic string value
    fake_widget( std::string( "Can't open file: " ).append( file_name ) );

    // Using std::to_string for non-string values
    fake_widget( std::string( "Volume = " ).append( std::to_string( volume ) ) );

    // A longer message
    fake_widget( std::string( "You have " )
                    .append( std::to_string( n_errors ) )
                    .append( " errors in " )
                    .append( std::to_string( n_files ) )
                    .append( " files." ) );
}

The output, as you might expect, is:

Can't open file: notes.txt
Volume = 6
You have 8 errors in 4 files.

Whether you use this technique, std::ostringstream or sprintf() is up to you and will often depend on the situation.