我试图使用vsnprintf
使用UTF-8字符格式化wchar_t*
,然后使用printf
打印缓冲区。wchar_t *在MSVC中使用UTF8字符
考虑下面的代码:
/*
This code is modified version of KB sample:
https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_73/rtref/vsnprintf.htm
The usage of `setlocale` is required by my real-world scenario,
but can be modified if that fixes the issue.
*/
#include <wchar.h>
#include <stdarg.h>
#include <stdio.h>
#include <locale.h>
#ifdef MSVC
#include <windows.h>
#endif
void vout(char *string, char *fmt, ...)
{
setlocale(LC_CTYPE, "en_US.UTF-8");
va_list arg_ptr;
va_start(arg_ptr, fmt);
vsnprintf(string, 100, fmt, arg_ptr);
va_end(arg_ptr);
}
int main(void)
{
setlocale(LC_ALL, "");
#ifdef MSVC
SetConsoleOutputCP(65001); // with or without; no dice
#endif
char string[100];
wchar_t arr[] = { 0x0119 };
vout(string, "%ls", arr);
printf("This string should have 'ę' (e with ogonek/tail) after colon: %s\n", string);
return 0;
}
我在Ubuntu 16 GCC编译V5.4以获得所需的输出BASH:
gcc test.c -o test_vsn
./test_vsn
This string should have 'ę' (e with ogonek/tail) after colon: ę
然而,在Windows 10 CL V19。 10.25019(VS 2017),我得到了CMD怪异输出:
cl test.c /Fetest_vsn /utf-8
.\test_vsn
This string should have 'T' (e with ogonek/tail) after colon: e
(在ę
冒号之前BECO MES T
和冒号后是不e
反尾形符)
注意,我使用的CL的新/utf-8
开关(VS 2015),这显然具有带或不带没有影响引入的。根据他们的blog post:
还有一个/ UTF-8选项用于设置的代名词“/源字符集:UTF-8”和“/运行,字符集:UTF-8”。
(我的源文件已经有BOM/utf8'ness和执行,字符集显然没有帮助)
什么可以修改代码/编译器开关的最小量,以使输出看起来相同到gcc的?
在Windows上,'printf()'(和通常的控制台)不支持UTF-8。您可以使用'WideCharToMultiByte()'(或等价的)将UTF-16编码的'wchar_t'数据转换为UTF-8,但这仍不能保证控制台能够正确显示它。您应该使用Unicode控制台API将Unicode数据写入控制台,例如C++中的Win32'WriteConsoleW()'函数或'std :: wcout'。关于如何将Unicode数据输出到Windows控制台,StackOverflow存在很多问题。你的声誉足够高,你应该知道在问之前做一些研究。 –
您也可以运行PowerShell IDE并导航到您的程序目录,然后运行您的程序。 –
@RemyLebeau,谢谢。我将尝试'WideCharToMultiByte()'和其他Unicode控制台API。我做了一些研究,但在产品版本中迷失了方向(例如自VS2015以来,包含vsnprintf OOTB等)。将阅读更多。 :) –