简单的答案
std::string
定义为std::basic_string<char>
意思是它是字符的集合。作为字符的集合,它可以潜在地保存作为编码结果的字符utf8 string.
以下代码有效直到 C++20:
std::string s = u8"1 שלום Hello";
std::cout << s << std::endl;
And 它打印,在支持它的控制台中:
1 你好
The u8
在括号内的字符串之前是字符串字面量 for utf8
告诉编译器以下带括号的字符串具有 utf8 编码。
如果没有u8
前缀表示法编译器将根据编译器的源编码获取字符串,因此如果默认编码或为编译器显式设置的编码支持字符串中的字符,它也可以像这样获取字符串:
std::string s = "1 שלום Hello";
std::cout << s << std::endl;
with 相同的输出如上。然而,这是依赖于平台和编译器的。
如果编译器的源编码不支持这些字符,例如,如果我们在 gcc 中将源编码设置为LATIN与旗帜-fexec-charset=ISO-8859-1
没有的字符串u8
prefix 给出以下编译错误:
converting to execution character set:
Invalid or incomplete multibyte or wide character
std::string s = "1 שלום Hello";
^~~~~~~~~~~~~~
从 C++20 开始 u8
带括号的字符串无法转换为std::string
:
std::string s = u8"1 שלום Hello";
std::cout << s << std::endl;
给出以下编译错误在 C++20 中:
conversion from 'const char8_t [17]' to non-scalar type 'std::string'
{aka 'std::__cxx11::basic_string<char>'} requested
std::string s = u8"1 שלום Hello";
^~~~~~~~~~~~~~~~~
这是因为类型u8
C++20 中带括号的字符串不是const char[SIZE]
反而const char8_t[SIZE]
(方式char8_t
在 C++20 中引入)。
You can use然而在 C++20 中新类型std::u8string
:
std::u8string s = u8"1 שלום Hello"; // good - std::u8string added in C++20
// std::cout << s << std::endl; // oops, std::ostream doesn't support u8string
一些有趣的注释:
-
直到 C++20 a
u8
带括号的字符串是const char[SIZE]
-
来自 C++20 a
u8
带括号的字符串是const char8_t[SIZE]
-
the size of
char8_t
是相同的char
, 但它是一个独特的类型
故事很长
在 C++ 中,编码是一个悲伤的故事。这可能就是为什么您的问题没有“简单答案”的原因。目前还没有一个成熟的端到端标准解决方案来处理字符编码。有标准转换器、第三方库等。但不是真正紧凑且简单的解决方案。希望 C++23 能够解决这个问题。
See 关于该主题的 CppCon 2019 会议,作者:JeanHeyd Meneide
还有一个相关问题:std::u8string 与 std::string 有何不同?