UTF8 console output: MultiByteToWideChar vs mbsrtowcs
我想从UTF-8文件中读取一小行并将其显示在Windows控制台中。
我成功使用WinByte函数的MultiByteToWideChar:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| void mbtowchar (const char* input , WCHAR * output ) {
int len = MultiByteToWideChar (CP_UTF8 , 0, input , -1, NULL , 0);
MultiByteToWideChar (CP_UTF8 , 0, input , -1, output , len );
}
void main () {
setlocale(LC_ALL ,"");
char in [256];
FILE * file = fopen("data.txt","r");
fgets(in , 255, file );
fclose(file );
mbtowchar (in , out );
printf("%ls",out );
} |
...但是我使用ISO mbsrtowcs函数失败(非ASCII字符被弄乱了):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| void main () {
setlocale(LC_ALL ,"");
char in [256];
wchar_t out [256];
FILE * file = fopen("data.txt","r");
fgets(in , 255, file );
fclose(file );
const char* p = in ;
mbstate_t mbs = 0;
mbsrt , &am , &mbs );
printf("%ls",out );
} |
我对mbsrtowcs是否做错了事,或者这两个功能之间有重要区别? 是否可以使用ISO功能在Windows控制台中可靠地打印UTF-8? (假定已安装匹配的控制台字体。)
注意:我使用MinGW gcc编译器。 C ++对我而言是不得已的解决方案,我想继续使用C。
-
您确定data.txt是UTF8编码的吗? 不确定printf是否支持Unicode-如果没有记错的话,有%S说明符。 不确定是否适用于Win32 wsprintf的标准printf。
-
是。 源文件和数据文件都位于UTF-8中。
-
希望您的项目使用UNICODE定义进行编译。 您可以尝试使用与printf等效的wprintf Unicode。 有关详细信息,请参见MSDN。
-
@ i486 printf仅用于显示Unicode字符。 OP的问题是关于使用标准C多字节/宽函数将UTF-8字符(来自外部)重新编码为UTF-16。
mbsrtowcs的"错误"是它将系统定义的8位字符(char)可变宽度编码转换为"宽"字符(wchar_t)的固定宽度数组。 今天,宽字符已被理解为Unicode代码点,但是"多字节"并不一定意味着UTF-8。 实际上,在Windows上,它指的是亚洲文字的各种pre-Unicode编码。 令人沮丧的是,Windows根本不支持UTF-8作为本机的"多字节"编码,而且显然永远也不会。
因此,尝试使用mbsrtowcs解释UTF-8的尝试注定在Win32上失败。 您将必须像第一个代码片段一样使用MultiByteToWideChar,或切换到将UTF-8转换为UTF-16的其他方法。 (由于UTF-8和UTF-16都编码UCS代码点,因此,如果您的目标是避免依赖专有扩展,则甚至可以编写自己的简单例程来执行此操作。)
-
为什么注定要失败?我没有找到详细说明的任何链接。我的意思是:如果多字节最初是为亚洲语言提供支持的,为什么它阻止了UTF-8支持? Isp;#39;是同一原理吗?
-
@JanTuroň<;一个小时?啊钡拇鸢钢籬ttp://stackoverflow.com/questions/2995111/why-isnt-utf-8-allowed-as-the-ansi-code-page>;因此我链接了一个问题t <; />;指向a <; a h"啊?http://www.siao2.com/2006/10/11/816996."啊?"啊?nofollow noreferrer>; blog pos <; />; Michael Kaplan对此进行了详细解释。简而言之,支持UTF-8将使实现和使用mul"啊钡拇胨龅哪承┘偕栉扌А4胍场S捎谒且埠献"啊?并且多字节支持已过时并且想要摆脱它,他们认为投入大量金钱和时间来扩展它以支持UTF-
- ?
- >