将const char*转换为const wchar_t*

8
我正在尝试使用Irrlicht创建一个程序,从用Lua编写的配置文件中加载某些内容,其中之一是窗口标题。然而,lua_tostring函数返回一个const char*,而Irrlicht设备的方法setWindowCaption期望一个const wchar_t*。我该如何将lua_tostring返回的字符串转换?
4个回答

7
在SO上有多个问题涉及Windows的问题,例如:
  1. char*转换为const wchar_t *
  2. 从unsigned char*转换为const wchar_t*
http://ubuntuforums.org/showthread.php?t=1579640上发布了一个不受平台限制的方法。这个网站的源代码如下(希望不会侵犯任何版权):
#include <locale>
#include <iostream>
#include <string>
#include <sstream>
using namespace std ;

wstring widen( const string& str )
{
    wostringstream wstm ;
    const ctype<wchar_t>& ctfacet = use_facet<ctype<wchar_t>>(wstm.getloc()) ;
    for( size_t i=0 ; i<str.size() ; ++i ) 
              wstm << ctfacet.widen( str[i] ) ;
    return wstm.str() ;
}

string narrow( const wstring& str )
{
    ostringstream stm ;

    // Incorrect code from the link
    // const ctype<char>& ctfacet = use_facet<ctype<char>>(stm.getloc());

    // Correct code.
    const ctype<wchar_t>& ctfacet = use_facet<ctype<wchar_t>>(stm.getloc());

    for( size_t i=0 ; i<str.size() ; ++i ) 
                  stm << ctfacet.narrow( str[i], 0 ) ;
    return stm.str() ;
}

int main()
{
  {
    const char* cstr = "abcdefghijkl" ;
    const wchar_t* wcstr = widen(cstr).c_str() ;
    wcout << wcstr << L'\n' ;
  }
  {  
    const wchar_t* wcstr = L"mnopqrstuvwx" ;
    const char* cstr = narrow(wcstr).c_str() ;
    cout << cstr << '\n' ;
  } 
}

通常情况下,我发现在Ubuntu中处理C++中的宽字符需要设置默认语言环境。实现方式的行为非常讽刺。在Unix领域中使用UTF-8时,语言环境对于窄宽转换几乎没有影响,但必须进行设置;而在Windows中使用各种单字节编码时,语言环境非常重要,但已经默认设置好了。 - Cheers and hth. - Alf

2
您可以使用 mbstowcs 函数来进行转换:
    wchar_t WBuf[100];
    mbstowcs(WBuf,lua_tostring( /*...*/ ),99);

更安全的方法:
    const char* sz = lua_tostring(/*...*/);
    std::vector<wchar_t> vec;
    size_t len = strlen(sz);
    vec.resize(len+1);
    mbstowcs(&vec[0],sz,len);
    const wchar_t* wsz = &vec[0];

0

对于 Unicode:

std::string myString = "Master James";
const char* sz = myString.c_str();
size_t origsizes = strlen(sz) + 1;
const size_t newsizes = 500;
size_t convertedCharP = 0;
wchar_t constTowchar[500];
mbstowcs_s(&convertedCharP, constTowchar, origsizes, sz, _TRUNCATE);
std::wcout << constTowchar << std::endl;

这个可以使用mbstowcs_s实现。


0

这里是第一个答案的更快版本代码,不要忘记对于某些字符使用std::locale::global(std::locale(""));

#include <xlocale>
#include <sstream>

[[nodiscard]] inline std::wstring widen(const char* str)
{
    const auto length = strlen(str);

    std::wstring result;
    result.resize(length);

    const auto& facet = use_facet<std::ctype<wchar_t>>(std::wostringstream().getloc());
    std::transform(str, str + length, result.begin(), [&facet](const char ch)
    {
        return facet.widen(ch);
    });
    return result;
}

[[nodiscard]] inline std::string narrow(const wchar_t* str)
{
    const auto length = wcslen(str);

    std::string result;
    result.resize(length);

    const auto& facet = use_facet<std::ctype<wchar_t>>(std::ostringstream().getloc());
    std::transform(str, str + length, result.begin(), [&facet](const wchar_t ch)
    {
        return facet.narrow(ch);
    });
    return result;
}

虽然您的回答可能回答了问题,但“仅代码”答案不被接受。请添加标题和一些解释以说明正在发生的事情。有关更多信息,请访问https://stackoverflow.com/help/how-to-answer。 - nurchi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接