字符*编码

Viv*_*mar 13 c++ encoding visual-c++

如果我在Visual Studio下用C++编写下面的语句,那么这里将编码什么?

const char *c = "£";
Run Code Online (Sandbox Code Playgroud)

在Visual Studio项目设置下,我将"Charset"设置为"Not set".

bam*_*s53 23

将charset设置为"Not Set"只意味着不会设置预处理器宏_UNICODE和_MBCS.这对编译器使用的字符集没有影响.

确定源的字节如何在程序中转换为字符串文字的两个设置是"源字符集"和"执行字符集".编译器将字符串文字从源编码转换为执行编码.

来源编码:

源编码是编译器用于解释源文件字节的编码.它不仅适用于字符串和字符文字,还适用于源代码中的所有其他内容,例如标识符.

如果Visual Studio的编译器在源文件中检测到Unicode'签名',那么它将使用相应的Unicode编码作为源编码.否则,它将使用系统的代码页编码作为源编码.

执行编码:

执行编码是编译器将字符串和字符文字存储为的编码,使得由文字创建的字符串和字符数据将使用执行编码进行编码.

Visual Studio的编译器使用系统的代码页作为执行编码.


当Visual Studio执行字符串和字符文字数据从源编码到执行编码的转换时,它将替换无法在执行编码集中用'?'表示的字符.

所以对于你的例子:

const char *c = "£";
Run Code Online (Sandbox Code Playgroud)

假设您的源使用Microsoft的"带签名的UTF-8"格式保存,并且您的系统使用CP1252作为西方的大多数系统,则字符串文字将转换为:

0xA3 0x00
Run Code Online (Sandbox Code Playgroud)

另一方面,如果执行字符集不包含'£',例如cp1251(西里尔语,在Window的俄语语言环境中使用),那么字符串文字将会结束:

0x3F 0x00
Run Code Online (Sandbox Code Playgroud)

如果您想避免依赖源代码编码,可以使用通用字符名称(UCN):

const char *c = "\u00A3"; // "£"
Run Code Online (Sandbox Code Playgroud)

如果要保证UTF-8表示,还需要避免依赖执行编码.您可以通过手动编码来实现:

const char *c = "\xC2\xA3"; // UTF-8 encoding of "£"
Run Code Online (Sandbox Code Playgroud)

C++ 11引入了UTF-8字符串文字,当编译器支持它们时会更好:

const char *c = u8"£";
Run Code Online (Sandbox Code Playgroud)

要么

const char *c = u8"\u00A3"; // "£"
Run Code Online (Sandbox Code Playgroud)