如何在二进制模式下读取UTF-8文件并使用C将其转换为UTF-16文件



我是这个Unicode世界的新手,我不知道如何使用C。我不在 *nix系统上。我正在使用Fedora Linux。我尝试以二进制模式打开UTF-8文件,然后将每个字节读取到整数中,然后将其转换为相应的Unicode Codepoint。但是事实是,我该如何使用UTF-16格式写入文本文件。

所得的UTF-16输出文件必须与刚刚读取的UTF-8文件相同,但以UTF-16格式相同。有人可以帮我吗?我应该从将UTF-8文件读取到整数开始吗?因为我很难阅读。我知道我的代码有点混乱,我正在努力使其变得更好。预先感谢!

首先,您必须确保您了解字符和编码点之间的区别。关于这个主题,我建议您阅读Joel Spolsky的这篇文章:绝对最低每个软件开发人员绝对必须了解Unicode和角色集(没有借口!(

然后,您可以在此处使用可用的convertutf库。尽管该库似乎不再由unicode.org支持。

在您的情况下,要从UTF8转换为UTF16,因此应使用" ConvertUtf8Toutf16"功能,该功能采用UTF8(无符号char(的输入缓冲区(未签名char(,并返回UTF16的输出缓冲区(无签名短(。

因此,要归结为您的问题:您应该将输入UTF8文件读为无符号字符的缓冲区,并将其写入输出UTF16文件作为无签名短的缓冲区。请注意端性。

最后一条警告:在微软世界中," Unicode"和utf16通常是等同的,但是在这种情况下," Unicode"的定义实际上是UCS-2大多数时候。

一种解决方案是使用Unicode库,例如ICU-TC,它将为您完成工作。

要避免库的依赖性,然后转换自己,您将需要读取并转换为32位无符号整数的可变长度UTF-8,然后将32位整数转换为UTF-16的16bit的可变长度编码-values。

您需要打开输出文件进行二进制写作,

FILE *outfile = fopen(filename,"wb");

UTF-16可以用很少的或大的Endian订购书写。为了消除歧义,UTF-16有一个特殊的字节订购代码点,您首先编写( 0xFEFF(这两个字节出现在文件中的顺序告诉读者文件已写入文件。(请参阅UTF-16说明中的说明在Wikipedia上(代码:

unsigned short int byte_ordering_sentinel = 0xFEFF;
fwrite(&byte_ordering_sentinel, 2, 1, outfile);

对于每个32位整数,您将需要遵循UTF-16规则以产生可变的长度UTF-16值。对于每个16位UTF-16值,您都会做:

fwrite(&next_utf16_value, 2, 1, outfile);

注意1 :endianness是您的CPU和操作系统的产物。英特尔CPU总是很少的。ARM CPU可以做,并且在Android下面是小的。如果您想更改输出的末日性,则需要在编写每个16位值之前字节汇编。请确保还要字节-SWAP初始BYTE_ORDERING_SENTINEL。

在Linux上,您可以在字节Wap.h。H。

中使用宏有效地字节交换。

注意2 :使用FgetC((时,必须检查一个EOF值。如果有人在您的程序运行时更改文件,则可能在您的FEOF(ARQ(检查与FGETC((调用之间存在竞赛条件。相反,您的循环看起来像这样:

while ( (num=fgetc(arq)) != EOF ) 

最新更新