C++ 文字和 Unicode

Posted

技术标签:

【中文标题】C++ 文字和 Unicode【英文标题】:C++ Literals and Unicode 【发布时间】:2017-07-10 07:07:30 【问题描述】:

C++ 文字

环境:

操作系统:Windows 10 专业版; 编译器:GCC 最新。 IDE:Code::Blocks 最新。 正在开发:控制台应用程序。

我对数字字面量前缀的理解是,它们对于确定数值类型很有用(不确定)。但是,我对字符和字符串字面量的前缀和后缀有很多困惑。我读了很多书,花了几天时间试图了解情况,但我得到了更多的问题和很少的答案。所以我认为堆栈溢出可能会有很大帮助。

问:

1- 字符串前缀 u8 u U L 的正确用法是什么?

我有以下代码作为示例:

#include <iostream>
#include <string>
using namespace std;

int main()

    cout << "\n\n Hello World! (plain) \n";
    cout << u8"\n Hello World! (u8) \n";
    cout << u"\n Hello World! (u) \n";
    cout << U"\n Hello World! (U) \n";
    cout << L"\n Hello World! (plain) \n\n";

    cout << "\n\n\n";

输出是这样的:

世界你好! (普通)

世界你好! (u8)

0x47f0580x47f0840x47f0d8

Q2:为什么 U u ans L 有这样的输出?我希望它只是确定类型而不是编码映射(如果是的话)。

Q3 是否有关于 UTF-8 等编码的简单且中肯的参考资料。我对它们感到困惑,此外我怀疑控制台应用程序是否能够处理它们。我认为理解它们至关重要。

Q4:我也将欣赏解释自定义类型文字的分步参考。

【问题讨论】:

"编译器:GCC 最新。" - 请给出版本号。完全有可能在您发表这篇文章和我发表评论之间,可能已经发布了一个新版本。也看看en.cppreference.com/w/cpp/language/string_literal 通常最好每个问题问一个问题。多个问题往往会导致答案杂乱无章,让未来的用户更难找到他们正在寻找的信息。 例如,回答 1 需要简短讨论字符编码,为什么 std::cout 似乎可以处理 UTF8,而 std::wcout 这将是一个很好的独立问题。 谢谢大家,我以后会考虑的。 【参考方案1】:

先见:http://en.cppreference.com/w/cpp/language/string_literal

std::cout 的类运算符&lt;&lt; 被正确重载以打印const char*。这就是打印前两个字符串的原因。

cout << "\n\n Hello World! (plain) \n";
cout << u8"\n Hello World! (u8) \n";

正如预期的那样,打印出1

Hello World! (plain)

Hello World! (u8)

同时std::cout的类对于const char16_t*const char32_t*const wchar_t*没有特殊的&lt;&lt;重载,因此它将匹配&lt;&lt;的打印指针重载,这就是原因:

cout << u"\n Hello World! (u) \n";
cout << U"\n Hello World! (U) \n";
cout << L"\n Hello World! (plain) \n\n";

打印:

0x47f0580x47f0840x47f0d8

如您所见,那里实际上打印了 3 个指针值:0x47f0580x47f0840x47f0d8


但是,对于最后一个,您可以使用 std::wcout 使其正确打印

std::wcout << L"\n Hello World! (plain) \n\n";

打印

 Hello World! (plain)

1:u8 文字按预期打印,因为 UTF-8 的前几个代码点的直接 ASCII mapping。

【讨论】:

值得指出的是,u8 打印是因为 utf8 的前几位被映射到 ascii。更复杂的字符串会被垃圾填充 @user4581301 更复杂的字符串将在健全的操作系统(也不是 Windows)上正确打印。 cout 不在乎,控制台驱动程序必须解释程序发送的多字节输出。【参考方案2】:

1) 窄多字节字符串文字。无前缀字符串字面量的类型是const char[]

2) 宽字符串文字。 L"..." 字符串文字的类型是 const wchar_t[]

3) UTF-8 编码的字符串文字。 u8"..." 字符串文字的类型是 const char[]

4) UTF-16 编码的字符串文字。 u"..." 字符串文字的类型是 const char16_t[]

5) UTF-32 编码的字符串文字。 U"..." 字符串文字的类型是 const char32_t[]

6) 原始字符串文字。用于避免任何字符的转义,分隔符之间的任何内容都将成为字符串的一部分。前缀(如果存在)具有与上述相同的含义。

std::cout 需要单字节字符,否则它可以输出一个值,例如0x47f0580x47f0840x47f0d8。如果您尝试输出由多字节字符(char16_t、char32_t 或 wchar_t)组成的文字,则需要使用 std::wcout 将它们输出到控制台,或将它们转换为单字节字符类型。原始字符串文字对于格式化输出非常方便。原始字符串文字的一个示例是R"~(This is the text that will be output just as I typed it into the code editor!)~",它将是一个单字节字符串。如果它以任何多字节限定符为前缀,则原始字符串文字将是多字节的。 Here 是关于字符串文字的非常全面的参考。

【讨论】:

以上是关于C++ 文字和 Unicode的主要内容,如果未能解决你的问题,请参考以下文章

C 和 C++ 中的多字符文字

python字符串

C++ 模板和字符串文字

c++如何改变控制台文字颜色

C++ 多行字符串文字

如何在C++中用文字制作图片的白色背景