繁体   English   中英

关于C/C++和Java的char code问题

[英]The question about the char code of C/C++ AND Java

我尝试使用 Unicode 代码 \U+1F431 输入表情符号的代码,如下所示:

图像

这是在 VS Studio 2019 上完成的。CPP 的文件编码是 UTF8-BOM。 C/C++语言中的char只占一个字节,说汉字需要两个字节2^16=65536。 在Java中,使用Unicode作为内码,char是UTF-16编码的,一个char是两个字节,需要用两个char(4个字节)来表示一个emoji,为什么emoji只用两个字节C 语言可以说吗?

In addition, in this online C++ runtime environment( https://c.runoob.com/compile/12 ), run the same code, output is 4, the character encoding of the http request from the page is UTF-8, the results I明白应该是UTF-8这个emoji编码的字节数,但是为什么和执行的结果不一样呢? C++程序的结果是否还会受到文件编码的影响? Java 中的任何文件编码始终相同

图像

#include <iostream>
#include <cstring>

int main()
{
    char str[] = "🐱";
    printf("%d", strlen(str));
    // output is 2 in VS Studio and 4 in the online C++ runtime environment

    char str1[] = "哈";
    printf("%d", strlen(str1));
    // output is 2 in VS Studio and 3 in the online C++ runtime environment
}

CPP 的文件编码为 UTF8-BOM。

我假设您正在谈论特定源文件的编码,而不是断言有关 C++ 语言的内容。 然而事实上,只要你和你的编译器同意并且编译器支持它,你的源文件的编码是无关紧要的。 C 和 C++ 区分源文件的编码(源字符集)和运行时字符数据的编码 memory(执行字符集)。 他们不要求这些相同。 在运行时执行的strlen() function 将评估 C 字符串文字的运行时编码中的字节数。

C/C++语言中的char只占一个字节,说汉字需要两个字节2^16=65536。

对汉字进行编码需要多少字节取决于字符和编码。 例如,使用 UCS-4 编码的 Unicode,所有字符都需要四个字节。

使用根据 UCS-2 编码的 Unicode,所有字符都需要两个字节,但根本可以表示少于 65536 个字符——Unicode“基本多语言平面”。 在这种编码中,所有可以表示的汉字都占两个字节,就像所有其他字符一样。

使用 UTF-16,一些字符需要两个字节,而另一些则需要四个。 Unicode 将许多它认为不太常用的汉字映射到 BMP 之外的代码点,这些在 UTF-16 中需要四个字节。

对于 UTF-8,BMP 之外的所有字符都需要四个字节。 大多数 BMP 字符需要三个字节,但有些需要更少。

这绝不是一个详尽的替代方案清单。

在Java中,使用Unicode作为内码,char是UTF-16编码的,一个char是两个字节,需要用两个char(4个字节)来表示一个emoji,为什么emoji只用两个字节C 语言可以说吗?

Unicode 编码 BMP 之外的所有表情符号 无论选择何种编码,两个字节都不足以传达它们的 Unicode 代码。 例如,您的特定表情符号是 U+1F431,“猫脸”。 其 Unicode 代码点有 17 个有效位。 它不能在 UCS-2 中表示,它在 UTF-16 中的表示有四个字节,它在 UTF-8 中的表示也有四个字节。

因此,您的程序的 output 可能表明源代码有问题或者它没有被 VS 正确构建。 您可能会以任何一种方式查看它,因为最可能的问题是 VS 假设的源字符集与实际编码源文件的字符集不同。 打印字符串也可能是有益的,而不仅仅是它们的长度,或者在运行时使用 VS 的调试器检查它们。

您的汉字示例是 Unicode 字符 U+54C8。 它在 UCS-2 和 UTF-16 中的表示有两个字节,而在 UTF-8 中的表示有三个字节。 VS 在这里再次做了一些奇怪的事情(见下文),可能又是因为你和它之间关于源字符集的分歧。

In addition, in this online C++ runtime environment( https://c.runoob.com/compile/12 ), run the same code, output is 4, the character encoding of the http request from the page is UTF-8, the results I明白应该是UTF-8这个emoji编码的字节数,但是为什么和执行的结果不一样呢?

是和不是。 您使用的在线环境不太可能(但并非不可能)考虑 HTTP 请求的编码来确定 C++ 实现的执行字符集,这对strlen()很重要。 但是,如果它有任何好处,那么它确实会考虑到源字符集的请求编码,或者通过转码为选择的标准编码,或者通过告诉编译器根据具体情况使用哪种源编码。 因此,有理由相信在线环境不会受到任何源编码分歧的影响,例如我在 VS 中提出的可能存在的问题。

UCS4、UCS-2 和 UTF-16 不是 C 和 C++ 的可行执行字符集,因为许多非空字符的编码包含 null 字节。 C 和 C++ 实现不会使用这些。 (宽字符串是一个不同的考虑因素。)实现可能有各种执行字符集的选项,但 UTF-8 是常见的默认值。 那是因为它是一个很好的选择,而不是因为任何特定外部数据的编码。

您的程序在在线环境中的 output 与 UTF-8 是该环境选择的执行字符集一致。

C++程序的结果是否还会受到文件编码的影响? Java 中的任何文件编码始终相同

C++ 程序的结果可能会受到实现的执行字符集的影响。 当涉及 I/O 时,您还必须考虑外部数据的编码。 正如您所观察到的,Java 是不同的——字符数据的内部表示形式就其char数据类型和java.lang.String class 而言不允许在不同的实现中有所不同。 但是,如果对源文件编码存在分歧,您可能仍然会遇到 Java 的问题,而对于 Java,您在执行 I/O 时仍然必须考虑字符编码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM