如何将单字节const char *转换为UTF-8编码

时间:2010-12-17 11:20:48

标签: c++ utf-8 character-encoding

我有一个函数,它要求我传递一个由char *指向的UTF-8字符串,并且我有一个指向单字节字符串的char指针。如何在C ++中将字符串转换为UTF-8编码?我可以使用任何代码来执行此操作吗? 谢谢!

3 个答案:

答案 0 :(得分:4)

假设Linux,你正在寻找iconv。当您打开转换器(iconv_open)时,将传递到编码。如果从传递空字符串作为,它将从系统上使用的与文件系统匹配的语言环境转换。

在Windows上,MultiByteToWideCharCP_ACP作为代码页传递时几乎完全相同。但在Windows上,您只需调用Unicode版本的函数即可立即获取Unicode,然后使用WideCharToMultiByteCP_UTF8转换为UTF-8。

答案 1 :(得分:2)

要将字符串转换为其他字符编码,请使用各种字符编码库。一个流行的选择是iconv(大多数Linux系统的标准)。

但是,要做到这一点,首先需要弄清楚输入的编码。遗憾的是,没有一般解决方案。如果输入没有指定其编码(例如网页通常这样做),你就必须猜测。

关于你的问题:你写的是在FAT32文件系统上调用readdir得到的字符串。我不太确定,但我相信readdir将返回文件系统存储的文件名。在FAT / FAT32的情况下:

  • 短文件名在一些DOS code page中编码 - 哪个代码页取决于文件的写入方式,没有办法从文件系统AFAIK中分辨出来。
  • 长文件名为UTF-16。

如果使用标准vfat Linux内核模块访问FAT32分区,则应从readdir获取长文件名(除非文件只有8.3名称)。 这些可以解码为UTF-16。 FAT32在内部以UTF-16存储长文件名。 vfat驱动程序会将它们转换为iocharset= mount参数给出的编码(默认情况下是默认的系统编码)。

其他信息:

您可能必须使用挂载选项codepageiocharset(请参阅http://linux.die.net/man/8/mount)来获取FAT32卷上的文件名。尝试安装,以便在Linux控制台中正确显示文件名,然后继续。这里有更多解释:http://www.nslu2-linux.org/wiki/HowTo/MountFATFileSystems

答案 2 :(得分:1)

我猜最高位是在1字节字符串上设置的,所以你传递给它的函数需要传递超过1个字节。

首先,以十六进制打印出字符串。

即。

unsigned char* str = "your string";
for (int i = 0; i < strlen(str); i++)
  printf("[%02x]", str[i]);

现在阅读有关UTF8编码的维基百科文章,这解释得很清楚 http://en.wikipedia.org/wiki/UTF-8

UTF-8是可变宽度,其中每个字符可占用1到4个字节。

因此,将十六进制转换为二进制,看看代码点是什么。

即。如果第一个字节开始11110(二进制),那么它期望一个4字节的字符串。由于ascii是7位0-127,因此最高位始终为零,因此应该只有1个字节。顺便说一句,UTF8字符串的宽字符中第一个字节后面的字节将为最高位开始“10 ...”。这些是连续字节......这就是你的函数所抱怨的...即,在预期时会丢失连续字节。 所以字符串不像你想象的那样真实。

您可以使用有人建议的iconv转换,也可以使用此库http://utfcpp.sourceforge.net/

转换