Nav*_*K N 2 c++ windows unicode
我有一个Windows应用程序,其中的字符串类型WCHAR*.我需要将其转换char*为传递给C API.我正在使用MultiByteToWideChar和WideCharToMultiByte执行转换功能.
但由于某种原因,转换是不恰当的.我在输出中看到很多胡言乱语.以下代码是此 stackoverflow答案中的修改版本.
WCHAR* convert_to_wstring(const char* str)
{
int size_needed = MultiByteToWideChar(CP_UTF8, 0, str, (int)strlen(str), NULL, 0);
WCHAR* wstrTo = (WCHAR*)malloc(size_needed);
MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)strlen(str), wstrTo, size_needed);
return wstrTo;
}
char* convert_from_wstring(const WCHAR* wstr)
{
int size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr, (int)wcslen(wstr), NULL, 0, NULL, NULL);
char* strTo = (char*)malloc(size_needed);
WideCharToMultiByte(CP_UTF8, 0, wstr, (int)wcslen(wstr), strTo, size_needed, NULL, NULL);
return strTo;
}
int main()
{
const WCHAR* wText = L"Wide string";
const char* text = convert_from_wstring(wText);
std::cout << text << "\n";
std::cout << convert_to_wstring("Multibyte string") << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Rem*_*eau 12
您的转换功能有问题.
返回值MultiByteToWideChar()是一些宽字符,而不是像您当前正在处理它的字节数.sizeof(WCHAR)调用时需要多次调整值malloc().
您还没有考虑到的返回值不包括空终止空间,因为你不及格-1的cbMultiByte参数.阅读MultiByteToWideChar()文档:
cbMultiByte[in] 参数
指示的字符串的大小(以字节为单位)lpMultiByteStr.或者,如果字符串以空值终止,则此参数可以设置为-1.请注意,如果cbMultiByte为0,则函数失败.如果此参数为-1,则该函数处理整个输入字符串,包括终止空字符.因此,生成的Unicode字符串具有终止空字符,并且函数返回的长度包括此字符.
如果此参数设置为正整数,则该函数将精确处理指定的字节数.如果提供的大小不包含终止空字符,则生成的Unicode字符串不以空值终止,并且返回的长度不包括此字符.
...
返回值
如果成功,则返回写入缓冲区的字符数
lpWideCharStr.如果函数成功且cchWideChar为0,则返回值是指示的缓冲区所需的大小(以字符为单位)lpWideCharStr.
您不是以null结尾输出字符串.
你的convert_from_wstring()功能也是如此.阅读WideCharToMultiByte()文档:
cchWideChar[in]
字符串的大小,以字符表示lpWideCharStr.或者,如果字符串以空值终止,则此参数可以设置为-1.如果cchWideChar设置为0,则函数失败.如果此参数为-1,则该函数处理整个输入字符串,包括终止空字符.因此,结果字符串具有终止空字符,并且函数返回的长度包括该字符.
如果此参数设置为正整数,则该函数将精确处理指定数量的字符.如果提供的大小不包含终止空字符,则生成的字符串不以空值终止,并且返回的长度不包括此字符.
...
返回值
返回写入成功时指向的缓冲区的字节数
lpMultiByteStr.如果函数成功且cbMultiByte为0,则返回值是指示的缓冲区所需的大小(以字节为单位)lpMultiByteStr.
话虽这么说,你的main()代码正在泄漏分配的字符串.由于它们已分配malloc(),因此您需要在free()使用它们时释放它们:
此外,您不能传递WCHAR*字符串std::cout.嗯,你可以,但它没有operator<<为宽字符串输入,但它确实有一个operator<<用于void*输入,所以它只会落得输出内存地址的WCHAR*所在,而不是实际的字符指向.如果要输出宽字符串,请std::wcout改用.
尝试更像这样的东西:
WCHAR* convert_to_wstring(const char* str)
{
int str_len = (int) strlen(str);
int num_chars = MultiByteToWideChar(CP_UTF8, 0, str, str_len, NULL, 0);
WCHAR* wstrTo = (WCHAR*) malloc((num_chars + 1) * sizeof(WCHAR));
if (wstrTo)
{
MultiByteToWideChar(CP_UTF8, 0, str, str_len, wstrTo, num_chars);
wstrTo[num_chars] = L'\0';
}
return wstrTo;
}
CHAR* convert_from_wstring(const WCHAR* wstr)
{
int wstr_len = (int) wcslen(wstr);
int num_chars = WideCharToMultiByte(CP_UTF8, 0, wstr, wstr_len, NULL, 0, NULL, NULL);
CHAR* strTo = (CHAR*) malloc((num_chars + 1) * sizeof(CHAR));
if (strTo)
{
WideCharToMultiByte(CP_UTF8, 0, wstr, wstr_len, strTo, num_chars, NULL, NULL);
strTo[num_chars] = '\0';
}
return strTo;
}
int main()
{
const WCHAR* wText = L"Wide string";
const char* text = convert_from_wstring(wText);
std::cout << text << "\n";
free(text);
const WCHAR *wtext = convert_to_wstring("Multibyte string");
std::wcout << wtext << "\n";
free(wtext);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
话虽这么说,你真的应该使用std::string和std::wstring替代char*,并wchar_t*为更好的内存管理:
std::wstring convert_to_wstring(const std::string &str)
{
int num_chars = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0);
std::wstring wstrTo;
if (num_chars)
{
wstrTo.resize(num_chars);
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &wstrTo[0], num_chars);
}
return wstrTo;
}
std::string convert_from_wstring(const std::wstring &wstr)
{
int num_chars = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.length(), NULL, 0, NULL, NULL);
std::string strTo;
if (num_chars > 0)
{
strTo.resize(num_chars);
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.length(), &strTo[0], num_chars, NULL, NULL);
}
return strTo;
}
int main()
{
const WCHAR* wText = L"Wide string";
const std::string text = convert_from_wstring(wText);
std::cout << text << "\n";
const std::wstring wtext = convert_to_wstring("Multibyte string");
std::wcout << wtext << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果您使用的是C++ 11或更高版本,请查看std::wstring_convert用于在UTF字符串之间进行转换的类,例如:
std::wstring convert_to_wstring(const std::string &str)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> conv;
return conv.from_bytes(str);
}
std::string convert_from_wstring(const std::wstring &wstr)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> conv;
return conv.to_bytes(wstr);
}
Run Code Online (Sandbox Code Playgroud)
如果你需要与基于char*/的其他代码交互wchar_t*,std::string作为接受char*输入的构造函数和c_str()可用于char*输出的方法,同样适用于std::wstring和wchar_t*.
| 归档时间: |
|
| 查看次数: |
2213 次 |
| 最近记录: |