C++ String Format with Examples

C++ String Format – C++ has had multiple attempts to bring text formatting to the language throughout its 40 years of history.

The first attempt was the printf() family of functions inherited from C.

std::printf("C++ is %s/n", "FUN!");

The prototype of printf is defined in the <cstdio> header file.

#include <cstdio>
int printf(const char * format, ...);

printf() and related functions have a simple API but only work with built-in C types(intconst char*strings, etc).

This can lead to type-safety issues and makes the multi-argument API based on varargs difficult to use.

People later started working on alternatives to the C programming language’s IO APIs that would be more type-safe and allow for the integration of user-defined types.

This work would eventually result in the creation of the standard <iostream> library.

const std::string fun{"FUN"};
std::cout << "C++ is" << fun << std::endl;

std::cout << "This "
               << "is "
               << certainly()
               << " not verbose "
               << *in_any_way 
               << std::endl;

Formatting Library <format>

The std::format class was added to C++ as part of the C++20 standard. Unless you compile it with C++20, std::format, it will not be available. If you insist on using the namespace std, an error will occur.

The format library’s main function is std::format() which formats the specified parameters and returns a string:

#include <format>

int main()
{
    const std::string sample_message = std::format("{} {}!", "C++ is", "FUN");
}

Placeholders can be indexed for rearranging arguments or repeating them.

For example, the two calls below both return "C++ is FUN!":

std::format("{1} {0}!", "FUN", "C++ is");
std::format("C{0}{0} is {1}!", "+", "FUN");

In addition to std::format(), the library contains std::format_to(), which writes the result string into an iterator.

This is useful for dumping formatted strings into iterator-based storage, like a file:

std::ofstream file{"MyFile.txt"};
std::format_to(std::ostream_iterator<char>(file), "C++ is {}!", "FUN");

or a container:

std::vector<char> buffer;
std::format_to(std::ostream_iterator<char>(buffer), "C++ is FUN!");

The format API supports all types, as long as a formatter is available for them.

There are predefined formats for built-in types, so in most cases, it will just work.

#include <iostream>
#include <chrono>
#include <format>
const std::string sample_countdown =
         std::format("{} days left till Christmas!", std::chrono::days(26));

Formatters return a string representation of a value and allow customizing the output.

Each type formatter has its own set of specifiers. For example, the floating-point formatter has a precision config:

// Save Planck's constant as a string that is accurate to three decimal places:
const std::string planck = std::format("{:.3f}", 6.62607015);

Declaration

The format() function declaration is as follows:

template< class... T >
std::string format( const std::locale& local, format, const T &... param );

// OR

template< class... T >
std::wstring format( const std::locale& local, format, const T &... param );

  • param: The strings are getting formatted.
  • format: The format string that was applied param in order to format it. This is a parameter of unspecified type.
  • local: This is an optional parameter that is used for formatting that is specific to the locale.

Return Value

C++ format() returns value:

  • If successful, it returns the total number of characters or a string with the param argument formatted as format.

  • The error indication (ferror) is set, and a negative integer is returned if a writing error occurs.

Exceptions

If the allocation fails, std::bad_alloc is thrown. Exceptions thrown by any formatter are also passed on.

Example 1:

#include <iostream>
#include <format>
 
int main() {
    std::format("Did you know that {} {}!", "C++", "is FUN", "Hello World");
}

Explanation:

The example above explains that it is not an error to give more arguments than what the format string needs.

Output

Did you know that C++ is FUN!

Example 2:

#include <iostream>
#include <format>
 
int main() {
    std::format("{0} is living in a very nice {1}, {0} thinks that she is in paradise!", "Grace", "Castle");
}

Explanation:

We can index placeholders to change the order of the arguments or even repeat them. Both of these calls return "Grace" and "Castle".

Output:

Anna is living in a very nice Castle, Anna thinks that she is in paradise!

Example 3:

#include <iostream>
#include <format>
 
int main() {
    std::cout << std::format("Greetings {}!! \n", "Prince");
    std::cout << std::format("I do {0} and I am {1} years old. \n", "Programming", "24");
}

Explanation:

The string "Prince" is represented by the symbol {}, which is a placeholder. The string "Prince" is substituted for {} at runtime. "Programming" is substituted for {0} and "24" is substituted for {1} at runtime.

Output:

Greetings Prince!!
I do Programming and I am 24 years old.

So far all the examples involved string arguments, but the format API supports all types, as long as a formatter is available for them. Formatters are available for built-in types like int, bool, std::string, and std::chrono::duration.

Summary

In summary, the C++ String format is a placeholder-based formatting syntax and formatting that is type-safe, utilizing variable templates for multiple argument support.

Support for custom formatted for user-defined types. I hope you understand what is String format using C++ Programming and how to use it properly.

Leave a Comment