首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MSVC中带有UTF8字符的UTF8

MSVC中带有UTF8字符的UTF8
EN

Stack Overflow用户
提问于 2017-08-01 23:54:33
回答 1查看 1.3K关注 0票数 3

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

考虑到以下代码:

代码语言:javascript
复制
/*
  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中获得所需的输出:

代码语言:javascript
复制
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中得到了奇怪的输出:

代码语言:javascript
复制
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中引入),这显然没有任何影响。基于他们的博客帖子

还有一个/utf-8选项,它是设置“/source-charset:utf-8”和“/execution:utf-8”的同义词。

(我的源文件已经具有BOM /utf8 8的特性,而且执行字符集显然没有帮助)

对代码/编译器开关的最小数量的更改可以使输出看起来与gcc的相同吗?

EN

回答 1

Stack Overflow用户

发布于 2017-08-02 12:47:22

基于@RemyLebeau的注释,我修改了代码,使用printf的w变体在Windows上获得与msvc相同的输出,与Unix上gcc的输出相匹配。

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

代码语言:javascript
复制
/*
  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))做同样的操作,我们还需要对stderr进行_setmode

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45449346

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档