所以我想解析IDv3.4文件。格式规范中有4种文本编码类型:ISO-8859-1UTF-16 with BOMUTF-16BEUTF-8。我已经编写了可以获取字节字符串的代码。
我的问题是如何将UTF-16 with BOMUTF-16BE字节打印到控制台。
还有一个重要的条件:我只能使用C库。我不能使用C++库。我甚至不能使用第三方C库。

最佳答案

一般来说(不是专门用于分析IDv3.4文件),您需要选择代码内部使用的公共字符编码;然后从任何其他字符编码转换为您选择的字符编码(对于输入数据,例如从用户或文件或网络),然后再次转换(对于输出,用户、文件或网络)。
选择公共字符编码:
你需要一些最小化“不可转换情况”的东西——例如,你不想选择ASCII,因为有太多的字符编码不能转换成ASCII。这主要意味着您需要使用Unicode编码。
你想要方便的东西。对于Unicode编码,这实际上只给了您两种选择:UTF-8(因为您不必关心endian问题,而且它在空间/内存消耗方面相对有效,而且像strlen()这样的C函数仍然可以工作)和UTF-32的版本(因为每个代码点占用固定的空间,并且它使转换更简单)。其中,UTF-32的好处基本上不重要(除非您正在使用字体呈现引擎)。
C编译器使用的“whatever random who known what”字符编码是不相关的(对于charw_char),因为它是特定于实现且不可移植的。
终端使用的“任何随机谁知道什么”字符编码是不相关的(终端应该被认为“只是输入/输出的另一种风格,其中涉及转换”)。
假设您选择UTF-8:
您可能可以强制编译器将字符串文本视为UTF-8(例如,在C++中类似于u8"hello",但我似乎找不到任何标准的C)。否则你需要在必要的时候自己动手。
我建议使用uint8_t类型来存储字符串;部分原因是char是“有符号的还是无符号的,这取决于风吹的方向”(这使得与其他字符编码的转换因“右移有符号/负数”问题而痛苦),部分原因是它有助于发现“意外使用的东西不是UTF-8”错误(例如编译器关于“从有符号到无符号的转换”的警告)。
UTF-8和UTF-32LE、UTF be、UTF-16LE、UTF be之间的转换相当简单(相关的维基百科文章足以描述它的工作原理)。
“带BOM的UTF-16”意味着前2个字节将告诉您它是UTF-16LE还是UTF-16BE,因此(在您添加了对UTF-16LE和UTF-16BE的支持之后)这很简单带BOM的UTF-32类似(前4个字节告诉您它是UTF32-BE还是UTF32-BE)。
从ISO-8859-1到UTF-8的转换相当简单,因为字符与具有相同值的Unicode代码点匹配。然而,人们常常会弄错(例如,当数据实际上被编码为Windows-1252时,就说它是ISO-8859-1);而要从UTF-8转换为ISO-8859-1,就需要处理“不可转换”的代码点。

关于c - 打印UTF-16字符串,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57939538/

10-14 18:42
查看更多