我在 Linux (Ubuntu 13.04) 中有一个 C 语言的程序。
#include<stdio.h>
int main()
{
char* cp = "ӐҖ";
printf("%s\n",cp);
printf("%d\n",sizeof(*cp));
printf("%d\n",(unsigned int)*cp);
return 0;
}
第一个和第二个 printf 的输出为:
ӐҖ
1
分别。
1.) 我首先担心的是,在第 3 个 printf 中,我试图将字符转换为 unsigned int 以试图查看表示第一个字符的 unicode 代码点,但我得到的是 -45。我应该使用什么最佳方法来查看由 1 字节“char”数据类型表示的单个 unicode 字符的 unicode 代码点?
2.) 第二个问题,当我将此代码移植到 Windows 7 时,[char* cp = "Ӑ͖";] 将导致编译器“警告 C4566:不能使用通用字符名称 '\uFFE6' 表示的字符在当前代码页 (932) 中表示”。当我运行它时,输出是:
??
1
Windows 不支持“char”数据类型中的 unicode 吗?那么我应该使用什么字符数据类型来让我的代码从 Linux 移植到 Windows?
最佳答案
C 不支持 Unicode。 C++也不行。如果您有兴趣,可以使用相应的库,或者如果需要,您可以手动编写自己的例程。
char
在 C 中不是“字符”类型,它是 byte 类型。我假设您使用 UTF-8 编写源代码。
GCC 按字面解释字符串文字中的字节。您已经定义了一个 5 字节的序列:d3 90 d2 96 00
。 (d3
解释为 signed char 是 -45。)您可以尝试使用 strlen
,它应该返回 4。大多数 Unix 和 C API 都是面向字节的,所以当您打印出这些字节,屏幕上显示的内容取决于终端仿真器使用的编码。通常它是 UTF-8,所以一切正常。
如果源是 UTF-8 格式,MSVC 会将字符串和字 rune 字视为您想要显示的内容(即文本),然后将它们编码为系统的默认代码页。所以如果你写"à"
,如果你使用CP-1252,它会被重新编码为e0 00
。如果您使用没有 à
的编码(例如您使用 CP-1250,它在 e0
处有 ŕ
),您将得到一个问题标记。
但是 MSVC 如何知道文件中的文本是什么?它查找 UTF-8 BOM。如果您的文本文件不是以 BOM 开头,MSVC 会假定文件的编码是默认的系统编码,并且不会尝试转换任何内容——它会保留所看到的字节,就像 GCC 一样。
(注意:我看到您使用 ShiftJIS;它可能会导致问题,因为它不兼容 ASCII,而且我不知道 MSVC 如何处理它。请谨慎行事。)
如果需要处理Unicode文本,使用MSVC,也可以使用wide string literals . GCC 也支持它们,尽管它缺少许多可以使用它们的库函数。但我是UTF-8 manifesto的坚定支持者并且我建议尽可能多地使用 UTF-8 字符串。
请注意,如果删除 BOM,则无法再在 MSVC 中使用宽字符串文字。
编辑:有关亚洲开发人员使用 MSCV 的更多讨论和经验,请参见此处:How to create a UTF-8 string literal in Visual C++ 2008长话短说:它并不漂亮。
关于linux - linux 中的 unicode 字符在 Windows 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23990237/