UTF8 控制台输出:MultiByteToWideChar 与 mbsrtowcs
UTF8 console output: MultiByteToWideChar vs mbsrtowcs
我想从 UTF-8 文件中读取一小段内容并将其显示在 Windows 控制台中。
我使用 MultiByteToWideChar Winapi 函数成功了:
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 字符乱七八糟):
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;
mbsrtowcs(out, &p, 255, &mbs);
printf("%ls",out);
}
我是不是对 mbsrtowcs 做错了什么,或者这两个函数之间有什么重要的区别?是否可以使用 ISO 函数在 windows 控制台中可靠地打印 UTF-8? (假设安装了匹配的控制台字体。)
注意:我使用 MinGW gcc 编译器。 C++ 是我最后的解决方案,我想继续使用 C。
"wrong" 与 mbsrtowcs
的区别在于,它将系统定义的 8 位字符可变宽度编码 (char
) 转换为 [= 的固定宽度数组=21=] 个字符 (wchar_t
)。宽字符今天被理解为 Unicode 代码点,但 "multi-byte" 并不一定意味着 UTF-8。在 Windows 上它实际上指的是 various pre-Unicode encodings of Asian scripts. Frustratingly, Windows doesn't support UTF-8 as a native "multi-byte" encoding at all, and apparently never will.
因此尝试使用 mbsrtowcs
来解释 UTF-8 在 Win32 上注定要失败。您将不得不像您的第一个代码片段那样使用 MultiByteToWideChar
,或者切换到其他将 UTF-8 转换为 UTF-16 的方法。 (由于 UTF-8 和 UTF-16 都对 UCS 代码点进行编码,如果您的目标是避免依赖专有扩展,您甚至可以自己编写一个简单的例程来执行此操作。)
我想从 UTF-8 文件中读取一小段内容并将其显示在 Windows 控制台中。
我使用 MultiByteToWideChar Winapi 函数成功了:
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 字符乱七八糟):
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;
mbsrtowcs(out, &p, 255, &mbs);
printf("%ls",out);
}
我是不是对 mbsrtowcs 做错了什么,或者这两个函数之间有什么重要的区别?是否可以使用 ISO 函数在 windows 控制台中可靠地打印 UTF-8? (假设安装了匹配的控制台字体。)
注意:我使用 MinGW gcc 编译器。 C++ 是我最后的解决方案,我想继续使用 C。
"wrong" 与 mbsrtowcs
的区别在于,它将系统定义的 8 位字符可变宽度编码 (char
) 转换为 [= 的固定宽度数组=21=] 个字符 (wchar_t
)。宽字符今天被理解为 Unicode 代码点,但 "multi-byte" 并不一定意味着 UTF-8。在 Windows 上它实际上指的是 various pre-Unicode encodings of Asian scripts. Frustratingly, Windows doesn't support UTF-8 as a native "multi-byte" encoding at all, and apparently never will.
因此尝试使用 mbsrtowcs
来解释 UTF-8 在 Win32 上注定要失败。您将不得不像您的第一个代码片段那样使用 MultiByteToWideChar
,或者切换到其他将 UTF-8 转换为 UTF-16 的方法。 (由于 UTF-8 和 UTF-16 都对 UCS 代码点进行编码,如果您的目标是避免依赖专有扩展,您甚至可以自己编写一个简单的例程来执行此操作。)