正如man 3p mbrtowc
所说,有四种结果类型可以返回: 0
如果字节被解码为NUL宽字符, {{1} } 如果序列被截断, (size_t)-2
如果序列是非法的,则其他值从零变化到多字节序列的长度。这里的一切都很清楚。 WinAPI怎么样?
有(size_t)-1
个功能,可以为MultiByteToWideChar
设置 ERROR_NO_UNICODE_TRANSLATION
(对应 (size_t)-1
), mbrtowc
和 ERROR_INVALID_FLAGS
(我认为它与 ERROR_INVALID_PARAMETER
相同)。我对 EINVAL
表示怀疑: 可能与ERROR_INSUFFICIENT_BUFFER
的 (size_t)-2
相同,但是从文档看来,它似乎只意味着宽字符的缓冲区不足以存储转换后的字符。
在不重新实现mbrtowc
和朋友的情况下,检索此类功能(如果可能)的常见做法是什么?是否有mbrtowc
替代品,在Windows中作为MultiByteToWideChar
使用?提前谢谢!
P上。 S.请不要在此建议使用UTF-8。我已经在任何可能的地方使用它了。但是,我必须处理Windows代码页,现在我正在寻找一种将多字节字符串转换为宽字符序列然后转换为Unicode字形数组的好方法(取决于sizeof(wchar_t),它意味着要么直接转换为UTF-32或首先从UTF-16解码)。我想知道是否必须因非法多字节序列而停止转换,或者由于给定的多字节序列不完整而可能继续转换。因此,请不要问为什么我也使用mbrtowc
:在将代码页转换为UTF-8或UTF-32之前,我必须在代码的某些部分处理代码页,所以这不是我自己的选择
答案 0 :(得分:1)
假设您正在谈论微软的Windows CRT,这是因为调用MultiByteToWideChar()设置EILSEQ并返回-1而导致错误的唯一结果。 Microsoft SDK源代码是公开可用的(大部分,无论如何),我建议简要地研究它以澄清情况。
要回答问题的“常见做法”部分,我会回答我现在的公司。对于我们需要获得精确和语义的情况,C库通常会让您失望,通常是由于错误(如本例所示)或有错误,或者只是没有与您的代码可能具有相同程度的错误处理质量。所以我们直接从具有我们想要的语义的包装器中调用MultiByteToWideChar()。
根据您想要获得的疯狂程度,即使是MultiByteToWideChar()也可能没有您想要的错误处理程度。微软掩盖了很多细节。如果你需要非常精确的语义,你可能想要使用独立的库,比如IBM的ICU,它将为你提供你可能需要的所有东西。
这一切都取决于你在处理问题时的准确程度。
答案 1 :(得分:0)
我找到了一个解决方案,如果您使用非UTF编码,可以更准确地处理MultiByteToWideChar
(因为我使用自己的函数来处理UTF-8,UTF-16和UTF- 32,这种方法似乎是最好的方法)。
所有人必须做的是遍历缓冲区中的每个单个字节(以空字符结尾的C字符串或某些数据)。在每个字符上,必须调用IsDBCSLeadByteEx
函数或使用带有GetCPInfoEx
结构的CPINFOEX
来检查当前字节是否应该跟随下一个字符。如果接下来有一个字节,则必须在两个字节上使用MultiByteToWideChar
(即字节数为2);如果当前字节后没有字节,则表示(size_t)-2
的结果与mbrtowc
相同。如果转化失败,则(size_t)-1
调用的结果与 mbrtowc
相同。