首页 > 解决方案 > 在 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

标签: c++windowsunicodeutf-8character-encoding

解决方案


您在这里使用了错误的说明符:

std::wstring msg = format_msg(L"msg: %S", u8"abc你好");

而不是%S,你想要%s。来自 MSDN 文档:

对于%s说明符:

与 printf 函数一起使用时,指定单字节或多字节字符串;当与 wprintf 函数一起使用时,指定一个宽字符串。字符显示到第一个空字符或达到精度值。

对于%S说明符:

当与 printf 函数一起使用时,指定一个宽字符串;与 wprintf 函数一起使用时,指定单字节或多字节字符串。字符显示到第一个空字符或达到精度值。

由于您的应用程序是 unicode,因此%s指定一个宽字符串。

附带说明一下,您不应将字符串函数(等)的通用“t”版本_vsctprintf_tcsstrtchar.h“t”版本(、、、_vscprintf_vscwprintfstrstr结合使用wcsstr。在 unicode 和非 unicode 之间切换时,这很容易破坏东西。


推荐阅读