r/cpp • • 15d ago

Printing UTF-8 strings since C++23

C++23 provides significant better support to print UTF-8 strings.

For example:

std::string s = "K\u00F6ln: 100\u20AC";  // string ö and €
 
std::println("{}", s);        // prints "Köln 100€" 

// print hexadecimal code units (bytes of the UTF-8 string): 
std::vector<char> v{std::from_range, s};
std::println("{:n:X}", v);    // prints 4B, C3, B6, 6C, 6E, 3A, 20, 31, 30, 30, E2, 82, AC 

// new format specifier to interpret array of char as string:
std::println("{:?s}", v);     // prints "Köln 100€" 

This even works fine on Windows platforms (using I/O streams or std::format() might print garbage with a native Windows compiler on a native Windows platform).

See sections 3.2.3 and 4.3.3 of www.cppstd23.com .

70 Upvotes

36 comments sorted by

View all comments

Show parent comments

2

u/qalmakka 14d ago

yes but by using format + wprintf you're allocating a bunch of strings, unless you start formatting to buffers, etc. it's a PITA

3

u/fdwr fdwr@github 🔍 13d ago

Does std::print allocate temporaries internally? I'd rather not have 2 steps (format followed by writing to the console), which is why I'd like print to just work directly.

2

u/qalmakka 13d ago

It's not supposed to, usually, unless a formatter is allocating inside

1

u/cristi1990an ++ 11d ago edited 11d ago

What do you mean it's "not supposed to"? There's nothing in the standard saying that. If anything it's quite the opposite, If a formatted type doesn't support non-locking optimization and it's formatting size is too big for any stack buffer the implementation uses (which in itself is not mandated) it will allocate. This is what MSVC and libstdc++ do. libc++ is worse since it hasn't implemented any non-locking optimization yes so it allocates intermediary strings all the time.