gpt4 book ai didi

c - wchar_t* 与 MSVC 中的 UTF8 字符

转载 作者:太空宇宙 更新时间:2023-11-04 00:00:49 25 4
gpt4 key购买 nike

我正在尝试使用 vsnprintfwchar_t* 格式化为 UTF-8 字符,然后使用 printf 打印缓冲区。

给定以下代码:

/*
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: ę

但是,在带有 CL v19.10.25019 (VS 2017) 的 Windows 10 上,我在 CMD 中得到奇怪的输出:

cl test.c /Fetest_vsn /utf-8
.\test_vsn
This string should have 'T' (e with ogonek / tail) after colon: e

(冒号前的ę变为T,冒号后的e没有ogonek)

请注意,我使用了 CL 的新 /utf-8 开关(在 VS 2015 中引入),无论有无,它显然都没有效果。基于他们的 blog post :

There is also a /utf-8 option that is a synonym for setting “/source-charset:utf-8” and “/execution-charset:utf-8”.

(我的源文件已经有 BOM/utf8'ness 并且执行字符集显然没有帮助)

要使输出看起来与 gcc 的输出相同,对代码/编译器开关的最小更改量是多少?

最佳答案

根据@RemyLebeau 的评论,我修改了代码以使用 printf API 的 w 变体,以获得与 Windows 上的 msvc 相同的输出,与 Unix 上的 gcc 相匹配。

此外,我现在没有更改代码页,而是使用了 _setmode (FILE 翻译模式)。

/*
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 _WIN32
#include <io.h> //for _setmode
#include <fcntl.h> //for _O_U16TEXT
#endif

void vout(wchar_t *string, wchar_t *fmt, ...)
{
setlocale(LC_CTYPE, "en_US.UTF-8");
va_list arg_ptr;

va_start(arg_ptr, fmt);
vswprintf(string, 100, fmt, arg_ptr);
va_end(arg_ptr);
}

int main(void)
{
setlocale(LC_ALL, "");
#ifdef _WIN32
int oldmode = _setmode(_fileno(stdout), _O_U16TEXT);
#endif

wchar_t string[100];

wchar_t arr[] = { 0x0119, L'\0' };
vout(string, L"%ls", arr);
wprintf(L"This string should have 'ę' (e with ogonek / tail) after colon: %ls\r\n", string);

#ifdef _WIN32
_setmode(_fileno(stdout), oldmode);
#endif
return 0;
}

或者,我们可以使用 fwprintf 并提供 stdout 作为第一个参数。要对 fwprintf(stderr,format,args)(或 perror(format, args))做同样的事情,我们需要 _setmode stderr 也是如此。

关于c - wchar_t* 与 MSVC 中的 UTF8 字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45449346/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com