拿wchar_t并放入char?

时间:2016-04-29 22:13:07

标签: c++

我已经尝试了一些事情并且还没有能够弄清楚如何将const wchar_t *text(如下所示)传递给变量StoreText(如下所示) 。我做错了什么?

void KeyboardComplete(int localClientNum, const wchar_t *text, unsigned int len)
{
    char* StoreText = text; //This is where error occurs
}

4 个答案:

答案 0 :(得分:5)

您无法直接wchar_t*分配给char*,因为它们是不同且不兼容的数据类型。

如果StoreText需要指向text指向的同一内存地址,例如,如果您计划循环遍历text数据的各个字节,那么简单的类型转换就足够了:

char* StoreText = (char*)text;

但是,如果预期StoreText指向其自己的字符数据的单独副本,则需要宽字符数据转换为窄字符数据。例如:

  • 在Windows上使用WideCharToMultiByte()功能:

    void KeyboardComplete(int localClientNum, const wchar_t *text, unsigned int len)
    {
        int StoreTextLen = 1 + WideCharToMultiByte(CP_ACP, 0, text, len, NULL, 0, NULL, NULL);
        std::vector<char> StoreTextBuffer(StoreTextLen);
        WideCharToMultiByte(CP_ACP, 0, text, len, &StoreTextBuffer[0], StoreTextLen, NULL, NULL);
    
        char* StoreText = &StoreText[0];
        //...
    }
    
  • 使用std::wcsrtombs()函数:

    #include <cwchar>  
    
    void KeyboardComplete(int localClientNum, const wchar_t *text, unsigned int len)
    {
        std::mbstate_t state = std::mbstate_t();
        int StoreTextLen = 1 + std::wcsrtombs(NULL, &text, 0, &state);
        std::vector<char> StoreTextBuffer(StoreTextLen);
        std::wcsrtombs(&StoreTextBuffer[0], &text, StoreTextLen, &state);
    
        char *StoreText = &StoreTextBuffer[0];
        //...
    }
    
  • 使用std::wstring_convert类(C ++ 11及更高版本):

    #include <locale>
    
    void KeyboardComplete(int localClientNum, const wchar_t *text, unsigned int len)
    {
        std::wstring_convert<std::codecvt<wchar_t, char, std::mbstate_t>> conv;
        std::string StoreTextBuffer = conv.to_bytes(text, text+len);
    
        char *StoreText = &StoreTextBuffer[0];
        //...
    }
    
  • 使用ICONVICU库中的类似转化。

答案 1 :(得分:0)

wchar_t是一个广泛的角色。每个字符通常为16或32位,但这取决于系统。

char是一个很好的'CHAR_BIT大小的数据类型。同样,它有多大依赖于系统。最有可能的是它将是一个字节,但我想不出CHAR_BIT不能为16或32位的原因,使其与wchar_t的大小相同。

如果它们的大小不同,则直接分配注定要失败。例如,对于16位char中的每1个字符,8位wchar_t将看到2个字符,很可能是2个完全不相关的字符。这很糟糕。

其次,即使它们的大小相同,它们也可能有不同的编码。例如,分配给字母“A”的数值可能与charwchar_t不同。它可以是char中的65和wchar_t中的16640。

要在不同的数据类型charwchar_t中有任何意义,需要将其转换为其他的编码。 std::wstring_convert通常会为您执行此翻译,但look into the locale library会为更复杂的翻译执行此翻译。两者都需要支持C ++ 11或更高版本的编译器。在以前的C ++标准中,small army of functions提供了转换支持。诸如Boost::locale之类的第三方库有助于统一并提供更广泛的支持。

操作系统提供转换功能,以便在OS使用的编码和其他常见编码之间进行转换。

答案 2 :(得分:0)

首先,对于字符串,您应该使用std::wstring/std::string而不是原始指针。

C ++ 11 Locale(http://en.cppreference.com/w/cpp/locale)库可用于将宽字符串转换为窄字符串。

我在下面编写了一个包装函数并使用了多年。希望它对你也有帮助。

#include <string>
#include <locale>
#include <codecvt>

std::string WstringToString(const std::wstring & wstr, const std::locale & loc /*= std::locale()*/)
{
    std::string buf(wstr.size(), 0);
    std::use_facet<std::ctype<wchar_t>>(loc).narrow(wstr.c_str(), wstr.c_str() + wstr.size(), '?', &buf[0]);
    return buf;
}

答案 3 :(得分:-2)

你必须进行演员表演,你可以这样做:

char* StoreText = (char*)text;

我认为这可行。

但是你可以使用cstdlib库的wcstombs函数。

char someText[12];
wcstombs(StoreText,text, 12);
  

最后一个参数大多数是指向数组中可用的字节数。