首页 > 解决方案 > MultibyteToWideChar 字节边界

问题描述

我正在尝试使用MultibyteToWideChar该函数支持的任何编码将某些文本转换为另一种编码,例如UTF-8.

问题是,MultibyteToWideChar当沿字符边界使用时,只会报告错误,但不会指示它在哪个字符处失败。拿着这个:

tes字hello

并说它是UTF-8。我想把它转换成UTF-16.

现在对于我的情况,我读了 4 个字节。然后,我调用MultibyteToWideChar这 4 个字节。好吧,亚洲字符分为两个边界。

现在MultibyteToWideChar会失败,并且不会告诉我哪个字节失败了,所以我可以重新调整。

我读了 4 个字节或 bufferSize 字节,因为我有流数据。

我已经使用iconv进行编码转换,但它太慢了。

我也用过ICU,它很快,但完全修剪后,它的大小仍然是 6.5MB,太大了。

是否有另一种解决方案也快速但体积小并支持广泛的编码?

我也尝试过 CharNextExA 函数等,但它们不适用于其他编码。

函数的返回值只返回字符,所以不知道转换了多少字节。多字节字符的长度可能不同。我需要转换的字节数,因为这样我可以将这些字节复制到下一个缓冲区中以供重用。

我正在尝试做的是以块的形式读取一个非常大的文件,并将该文件编码转换为 UTF-8

注意

我很好奇,ICU4C 是如何工作的?基本上,我将源文件复制过来,但开箱即用它只支持像 UTF-8 这样的编码,但不支持 Big5。要添加 Big5,我必须创建一个 5MB 的 .data 文件,然后将其发送到 ICU4C,然后 Big5 可用。问题是,我不认为 .data 文件是代码。因为当为 x64 编译时,它在 x86 上工作得非常好。有没有办法避免 5MB?

标签: c++winapiunicodeencodingutf-8

解决方案


我不认为有一个单一的功能解决方案。

如果不使用 3rd-party 库,您可能会遇到以下问题:

  • 将一个字节读入缓冲区。
  • 如果IsDBCSLeadByteEx为真,则将下一个字节附加到缓冲区。
  • 打电话MultiByteToWideChar。如果失败,则尾随字节(如果有)不正确。

请注意,IsDBCSLeadByteEx它不支持 Unicode,因此当代码页为 UTF-8 时,您需要自行处理长度,直到缓冲区包含一个完整的代码点。


推荐阅读