C++11coreintermediate
Unicode String Literals (C++11 Addition)
C++11 · Modern Revolution · Compiler flag: -std=c++11
Explanation
New string literal prefixes `u8`, `u`, and `U` create strings encoded in UTF-8, UTF-16, and UTF-32 respectively, providing explicit control over string encoding.
Real-World Scenario
Define multi-language UI strings with guaranteed encoding for an internationalized application.
Quick Snippet
snippet.cpp
const char* utf8 = u8"Hello \u00E9"; // UTF-8
const char16_t* utf16 = u"Hello \u00E9"; // UTF-16
const char32_t* utf32 = U"Hello \U0001F600"; // UTF-32Full Example
unicode_string_literals.cpp
// CodeNebula - C++11 Example: Unicode String Literals
// Compile: g++ -std=c++11 -Wall -Wextra -o example unicode_string_literals.cpp
//
// This example demonstrates:
// - u8"" for UTF-8 encoded string literals
// - u"" for UTF-16 encoded string literals (char16_t)
// - U"" for UTF-32 encoded string literals (char32_t)
// - Raw string literals combined with Unicode prefixes
// - Size differences between encodings
#include <iostream>
#include <cstdint>
#include <cstring>
// ============================================================
// 1. Helper to print byte contents
// ============================================================
void printBytes(const char* label, const void* data, size_t len) {
const unsigned char* bytes = static_cast<const unsigned char*>(data);
std::cout << " " << label << " (" << len << " bytes): ";
for (size_t i = 0; i < len && i < 20; ++i) {
if (i > 0) std::cout << " ";
std::cout << std::hex;
if (bytes[i] < 0x10) std::cout << "0";
std::cout << static_cast<unsigned>(bytes[i]);
}
if (len > 20) std::cout << " ...";
std::cout << std::dec << std::endl;
}
// ============================================================
// 2. UTF-8 string literals (u8"")
// ============================================================
void demonstrateUtf8() {
std::cout << "--- UTF-8 strings (u8\"\") ---" << std::endl;
const char* ascii = u8"Hello";
std::cout << " u8\"Hello\": " << ascii << std::endl;
std::cout << " strlen: " << std::strlen(ascii) << std::endl;
// Multi-byte characters in UTF-8
const char* withEuro = u8"Cost: \u20AC100";
std::cout << " u8\"Cost: <euro>100\": " << withEuro << std::endl;
std::cout << " strlen: " << std::strlen(withEuro)
<< " (euro = 3 bytes in UTF-8)" << std::endl;
printBytes("u8\"AB\"", u8"AB", 2);
}
// ============================================================
// 3. UTF-16 string literals (u"")
// ============================================================
void demonstrateUtf16() {
std::cout << "\n--- UTF-16 strings (u\"\") ---" << std::endl;
const char16_t* hello = u"Hello";
size_t len = 0;
while (hello[len] != 0) ++len;
std::cout << " u\"Hello\" length: " << len << " code units" << std::endl;
std::cout << " Total bytes: " << len * sizeof(char16_t) << std::endl;
// BMP characters fit in one char16_t
const char16_t* withEuro = u"Price: \u20AC50";
size_t elen = 0;
while (withEuro[elen] != 0) ++elen;
std::cout << " u\"Price: <euro>50\" length: " << elen << " code units" << std::endl;
printBytes("u\"AB\"", u"AB", 4);
}
// ============================================================
// 4. UTF-32 string literals (U"")
// ============================================================
void demonstrateUtf32() {
std::cout << "\n--- UTF-32 strings (U\"\") ---" << std::endl;
const char32_t* hello = U"Hello";
size_t len = 0;
while (hello[len] != 0) ++len;
std::cout << " U\"Hello\" length: " << len << " code points" << std::endl;
std::cout << " Total bytes: " << len * sizeof(char32_t) << std::endl;
// Every character is exactly one char32_t
const char32_t* mixed = U"A\u20AC\U0001F600"; // A + Euro + Smiley
size_t mlen = 0;
while (mixed[mlen] != 0) ++mlen;
std::cout << " U\"A<euro><smiley>\" length: " << mlen << " code points" << std::endl;
printBytes("U\"AB\"", U"AB", 8);
}
// ============================================================
// 5. Encoding size comparison
// ============================================================
void compareSizes() {
std::cout << "\n--- Encoding size comparison for 'A' ---" << std::endl;
std::cout << " u8\"A\": " << std::strlen(u8"A") << " byte(s)" << std::endl;
const char16_t* u16a = u"A";
size_t l16 = 0; while (u16a[l16]) ++l16;
std::cout << " u\"A\": " << l16 * sizeof(char16_t) << " byte(s)" << std::endl;
const char32_t* u32a = U"A";
size_t l32 = 0; while (u32a[l32]) ++l32;
std::cout << " U\"A\": " << l32 * sizeof(char32_t) << " byte(s)" << std::endl;
}
int main() {
std::cout << "=== Unicode String Literals ===" << std::endl;
demonstrateUtf8();
demonstrateUtf16();
demonstrateUtf32();
compareSizes();
return 0;
}
// Expected output:
// === Unicode String Literals ===
// --- UTF-8 strings (u8"") ---
// u8"Hello": Hello
// strlen: 5
// u8"Cost: <euro>100": Cost: ...100
// strlen: 11 (euro = 3 bytes in UTF-8)
// u8"AB" (2 bytes): 41 42
//
// --- UTF-16 strings (u"") ---
// u"Hello" length: 5 code units
// Total bytes: 10
// u"Price: <euro>50" length: 11 code units
// u"AB" (4 bytes): 41 00 42 00
//
// --- UTF-32 strings (U"") ---
// U"Hello" length: 5 code points
// Total bytes: 20
// U"A<euro><smiley>" length: 3 code points
// U"AB" (8 bytes): 41 00 00 00 42 00 00 00
//
// --- Encoding size comparison for 'A' ---
// u8"A": 1 byte(s)
// u"A": 2 byte(s)
// U"A": 4 byte(s)
Run command
g++ -std=c++11 -Wall -Wextra -o example unicode_string_literals.cpp