C++ Strings & Text: string_view, std::format, std::print, Unicode & Custom Formatters (C++23)

C++ Strings & Text: string_view, std::format, std::print, Unicode & Custom Formatters (C++23)
Table of Contents
- std::string Internals: SSO and Heap Allocation
- std::string_view: Zero-Copy String Observation
- string_view Pitfalls: Lifetime and Null Termination
- std::format: Modern Type-Safe Formatting (C++20)
- Format Specifiers: Alignment, Precision & Fill
- std::print and std::println: Direct Output (C++23)
- Custom std::formatter Specialization
- std::from_chars and std::to_chars: Zero-Allocation Conversion
- String Manipulation: Split, Trim, Replace
- Unicode and UTF-8 in C++
- Frequently Asked Questions
- Key Takeaway
std::string Internals: SSO and Heap Allocation
std::string uses Small String Optimization (SSO): strings up to ~15 bytes (implementation-defined) are stored in the stack portion of the string object itself — zero heap allocation:
std::string_view: Zero-Copy String Observation
std::string_view is a non-owning, read-only reference to a character sequence. It holds a pointer + length — no allocation, no copy:
string_view Pitfalls: Lifetime and Null Termination
std::format: Modern Type-Safe Formatting (C++20)
std::format provides Python/Rust-style format strings with compile-time format string validation:
Format Specifiers: Alignment, Precision & Fill
std::print and std::println: Direct Output (C++23)
std::print (C++23) combines formatting and output — thread-safe, faster than cout, safer than printf:
Custom std::formatter Specialization
Make your own types work with std::format and std::print:
std::from_chars and std::to_chars: Zero-Allocation Conversion
std::from_chars/std::to_chars are the fastest string-number conversion functions in C++ — no allocation, no locale, no exceptions:
Frequently Asked Questions
When should I use string_view vs const string&?
Use std::string_view when the function only reads the string and the caller might be passing a literal, const char*, or part of a string. Use const std::string& when you need null termination (e.g., passing to a C API that requires it) or when you need guaranteed std::string operations like .c_str(). In new code, prefer string_view — it's strictly more flexible.
Is std::format slower than printf at runtime?
For constant format strings, std::format validates the format at compile time and has runtime performance comparable to or better than printf. For dynamic format strings, std::vformat has overhead. In benchmarks, std::print is consistently faster than std::cout formatted output because it avoids std::ios synchronization. Fastest is always std::to_chars + write() for number formatting.
How do I handle UTF-8 strings in C++?
C++ doesn't natively understand Unicode grapheme clusters. The practical approach: use std::string as a container of raw UTF-8 bytes (correct — UTF-8 strings are valid byte sequences), use a library like ICU or utfcpp for grapheme-aware operations, and use std::format / std::print which handle UTF-8 output correctly on modern terminals.
Key Takeaway
Modern C++ text handling is categorized by ownership: std::string owns, std::string_view observes. For output, the 2026 standard is std::print/std::println — type-safe, fast, thread-safe. For numeric conversion, from_chars/to_chars are the zero-overhead workhorses. Custom std::formatter specializations make your types first-class citizens in the entire formatting ecosystem.
Read next: STL Containers Deep Dive: vector, map, unordered_map →
Part of the C++ Mastery Course — 30 modules from modern C++ basics to expert systems engineering.
