我已经尝试了一些事情并且还没有能够弄清楚如何将const wchar_t *text
(如下所示)传递给变量StoreText
(如下所示) 。我做错了什么?
void KeyboardComplete(int localClientNum, const wchar_t *text, unsigned int len)
{
char* StoreText = text; //This is where error occurs
}
答案 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];
//...
}
答案 1 :(得分:0)
wchar_t
是一个广泛的角色。每个字符通常为16或32位,但这取决于系统。
char
是一个很好的'CHAR_BIT
大小的数据类型。同样,它有多大依赖于系统。最有可能的是它将是一个字节,但我想不出CHAR_BIT
不能为16或32位的原因,使其与wchar_t的大小相同。
如果它们的大小不同,则直接分配注定要失败。例如,对于16位char
中的每1个字符,8位wchar_t
将看到2个字符,很可能是2个完全不相关的字符。这很糟糕。
其次,即使它们的大小相同,它们也可能有不同的编码。例如,分配给字母“A”的数值可能与char
和wchar_t
不同。它可以是char
中的65和wchar_t
中的16640。
要在不同的数据类型char
和wchar_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);
最后一个参数大多数是指向数组中可用的字节数。