我已经阅读了关于WideCharToMultiByte的文档,但我卡在这个参数上:
lpMultiByteStr
[out] Pointer to a buffer that receives the converted string.
我不太确定如何正确初始化变量并将其传递给函数。
我已经阅读了关于WideCharToMultiByte的文档,但我卡在这个参数上:
lpMultiByteStr
[out] Pointer to a buffer that receives the converted string.
我不太确定如何正确初始化变量并将其传递给函数。
这里有一对函数(基于Brian Bondy的示例),使用WideCharToMultiByte和MultiByteToWideChar来转换std::wstring和std::string之间的数据,以utf8编码,以避免丢失任何数据。
// Convert a wide Unicode string to an UTF8 string
std::string utf8_encode(const std::wstring &wstr)
{
if( wstr.empty() ) return std::string();
int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
std::string strTo( size_needed, 0 );
WideCharToMultiByte (CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
return strTo;
}
// Convert an UTF8 string to a wide Unicode String
std::wstring utf8_decode(const std::string &str)
{
if( str.empty() ) return std::wstring();
int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
std::wstring wstrTo( size_needed, 0 );
MultiByteToWideChar (CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
return wstrTo;
}
<codecvt>
,类似的事情已经成为了某种强制要求。例如:https://dev59.com/3LTma4cB1Zd3GeqP-Kul。 - kayleeFrye_onDeck在Brian R. Bondy提供的答案上作详细说明:下面是一个例子,说明为什么你不能简单地将输出缓冲区大小设置为源字符串中宽字符的数量:
#include <windows.h>
#include <stdio.h>
#include <wchar.h>
#include <string.h>
/* string consisting of several Asian characters */
wchar_t wcsString[] = L"\u9580\u961c\u9640\u963f\u963b\u9644";
int main()
{
size_t wcsChars = wcslen( wcsString);
size_t sizeRequired = WideCharToMultiByte( 950, 0, wcsString, -1,
NULL, 0, NULL, NULL);
printf( "Wide chars in wcsString: %u\n", wcsChars);
printf( "Bytes required for CP950 encoding (excluding NUL terminator): %u\n",
sizeRequired-1);
sizeRequired = WideCharToMultiByte( CP_UTF8, 0, wcsString, -1,
NULL, 0, NULL, NULL);
printf( "Bytes required for UTF8 encoding (excluding NUL terminator): %u\n",
sizeRequired-1);
}
输出结果为:
Wide chars in wcsString: 6
Bytes required for CP950 encoding (excluding NUL terminator): 12
Bytes required for UTF8 encoding (excluding NUL terminator): 18
通过创建一个新的 char 数组来使用 lpMultiByteStr [out] 参数。然后,您将该 char 数组传入以获取填充。您只需要初始化字符串的长度+1,以便在转换后获得一个空终止字符串。
下面是一些有用的辅助函数,它们展示了所有参数的用法。
#include <string>
std::string wstrtostr(const std::wstring &wstr)
{
// Convert a Unicode string to an ASCII string
std::string strTo;
char *szTo = new char[wstr.length() + 1];
szTo[wstr.size()] = '\0';
WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, szTo, (int)wstr.length(), NULL, NULL);
strTo = szTo;
delete[] szTo;
return strTo;
}
std::wstring strtowstr(const std::string &str)
{
// Convert an ASCII string to a Unicode String
std::wstring wstrTo;
wchar_t *wszTo = new wchar_t[str.length() + 1];
wszTo[str.size()] = L'\0';
MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, wszTo, (int)str.length());
wstrTo = wszTo;
delete[] wszTo;
return wstrTo;
}
无论何时在文档中看到一个参数是指向某种类型的指针,并且它们告诉你这是一个输出变量,那么你就需要创建该类型,然后传入一个指向它的指针。函数将使用该指针来填充您的变量。
因此,您可以更好地理解这一点:
//pX is an out parameter, it fills your variable with 10.
void fillXWith10(int *pX)
{
*pX = 10;
}
int main(int argc, char ** argv)
{
int X;
fillXWith10(&X);
return 0;
}
WideCharToMultiByte
和MultiByteToWideChar
的C语言实现。在两种情况下,我都确保在目标缓冲区的末尾添加了一个null
字符。
并且如果在输入字符串长度中显式指定没有终止的null字符,则MultiByteToWideChar不会对输出字符串进行null终止。
即使有人指定如果在输入字符串长度中显式指定没有终止的null字符,则WideCharToMultiByte不会对输出字符串进行null终止。
-1
并传入一个以null
结尾的字符串,我仍会为另一个null
字符分配足够的空间,因为对于我的用例,这并不是问题。wchar_t* utf8_decode( const char* str, int nbytes ) {
int nchars = 0;
if ( ( nchars = MultiByteToWideChar( CP_UTF8,
MB_ERR_INVALID_CHARS, str, nbytes, NULL, 0 ) ) == 0 ) {
return NULL;
}
wchar_t* wstr = NULL;
if ( !( wstr = malloc( ( ( size_t )nchars + 1 ) * sizeof( wchar_t ) ) ) ) {
return NULL;
}
wstr[ nchars ] = L'\0';
if ( MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS,
str, nbytes, wstr, ( size_t )nchars ) == 0 ) {
free( wstr );
return NULL;
}
return wstr;
}
char* utf8_encode( const wchar_t* wstr, int nchars ) {
int nbytes = 0;
if ( ( nbytes = WideCharToMultiByte( CP_UTF8, WC_ERR_INVALID_CHARS,
wstr, nchars, NULL, 0, NULL, NULL ) ) == 0 ) {
return NULL;
}
char* str = NULL;
if ( !( str = malloc( ( size_t )nbytes + 1 ) ) ) {
return NULL;
}
str[ nbytes ] = '\0';
if ( WideCharToMultiByte( CP_UTF8, WC_ERR_INVALID_CHARS,
wstr, nchars, str, nbytes, NULL, NULL ) == 0 ) {
free( str );
return NULL;
}
return str;
}