c++ - 在 Windows 上使用 _vscwprintf 处理 utf-8 编码字符串时失败
问题描述
static std::wstring format_string(CONST WCHAR* pszText, ...)
{
std::wstring result;
va_list args;
va_start(args, pszText);
int len = _vscwprintf(pszText, args);
if (len < 0)
{
wprintf_s(L"_vscwprintf failed, len=%i, error=%i\n", len, errno);
return L"";
}
result.resize((size_t)len);
vswprintf_s(const_cast<WCHAR*>(result.data()), result.size() + sizeof(WCHAR),
pszText, args);
va_end(args);
return result;
}
int wmain(int argc, wchar_t* argv[])
{
wprintf_s(L"%S\n", setlocale(LC_ALL, ".UTF8"));
std::wstring msg = format_string(L"msg: %S", u8"abc你好");
wprintf_s(L"msg: %s\n", msg.c_str());
return 0;
}
输出:
Chinese (Simplified)_China.utf8
_vsctprintf failed, len=-1, error=0
msg:
环境:
OS: Windows 10
Compiler: vs2019, mingw-w64-v8.1.0
Project Charset:UNICODE
为什么 _vsctprintf 失败,如何解决?有没有办法使用 _vsctprintf 来处理 utf-8 utf-8 编码的字符串?希望可以有人帮帮我。谢谢!
完整的项目文件:test_utf8.zip
解决方案
您在这里使用了错误的说明符:
std::wstring msg = format_msg(L"msg: %S", u8"abc你好");
而不是%S
,你想要%s
。来自 MSDN 文档:
对于%s
说明符:
与 printf 函数一起使用时,指定单字节或多字节字符串;当与 wprintf 函数一起使用时,指定一个宽字符串。字符显示到第一个空字符或达到精度值。
对于%S
说明符:
当与 printf 函数一起使用时,指定一个宽字符串;与 wprintf 函数一起使用时,指定单字节或多字节字符串。字符显示到第一个空字符或达到精度值。
由于您的应用程序是 unicode,因此%s
指定一个宽字符串。
附带说明一下,您不应将字符串函数(等)的通用“t”版本_vsctprintf
与_tcsstr
非tchar.h
“t”版本(、、、_vscprintf
等_vscwprintf
)strstr
结合使用wcsstr
。在 unicode 和非 unicode 之间切换时,这很容易破坏东西。
推荐阅读
- jupyter-notebook - Airflow Dag 文件夹 - 如何忽略笔记本检查点
- c - 为什么我得到 0 而不是 C 中计算 x - y 和 x/y 的结果
- angular - 在 ngFor 期间并排显示当前和下一条记录
- python - 如何制作这个循环?
- javascript - JackBox- 响应式灯箱 - 图像查看器,使用 Javascript 函数而不是 href
- ruby - 文件在进程妖魔化时重新打开
- c++ - lambda 如何在 MSVC2017 15.9.3 和 /std:c++17 中使用静态局部错误返回值?
- jakarta-ee - 如何使用 Cachecontrol 和 etag 缓存列表对象?
- angular - 如何在 Angular 中获取响应式表单输入的值?
- android - ADAL 身份验证需要在 Android 上管理的设备