C++ 如何使用MultiByteToWideChar?
我想将普通的C++ 如何使用MultiByteToWideChar?,c++,winapi,visual-c++,character-encoding,C++,Winapi,Visual C++,Character Encoding,我想将普通的字符串转换为wstring。为此,我尝试使用WindowsAPI函数。 但这对我不起作用 以下是我所做的: string x = "This is c++ not java"; wstring Wstring; MultiByteToWideChar( CP_UTF8 , 0 , x.c_str() , x.size() , &Wstring , 0 ); 最后一行生成编译器错误: 'MultiByteToWideChar':无法将参数5从'std::wstring*'转
字符串
转换为wstring
。为此,我尝试使用WindowsAPI函数。
但这对我不起作用
以下是我所做的:
string x = "This is c++ not java";
wstring Wstring;
MultiByteToWideChar( CP_UTF8 , 0 , x.c_str() , x.size() , &Wstring , 0 );
最后一行生成编译器错误:
'MultiByteToWideChar':无法将参数5从'std::wstring*'转换为'LPWSTR'
如何修复此错误
另外,参数
cchWideChar
的值应该是多少?0是吗?< /P> < P>函数不能接受指向C++字符串的指针。它需要一个指向足够大的宽字符缓冲区的指针-您必须自己分配这个缓冲区
string x = "This is c++ not java";
wstring Wstring;
Wstring.resize(x.size());
int c = MultiByteToWideChar( CP_UTF8 , 0 , x.c_str() , x.size() , &Wstring[0], 0 );
您必须调用
MultiByteToWideChar
两次:
MultiByteToWideChar
用于查找宽字符串所需的缓冲区大小。看看它说:
如果函数成功且cchWideChar为0,则返回值为LPWIDECHARST指示的缓冲区所需的大小(以字符为单位)
因此,要使
MultiByteToWideChar
为您提供所需的大小,请将0作为最后一个参数cchWideChar
的值传递。您还应该将NULL
作为前面的传递,lpWideCharStr
MultiByteToWideChar
。这一次,最后一个参数应该是缓冲区的实际大小,而不是0int wchars_num = MultiByteToWideChar( CP_UTF8 , 0 , x.c_str() , -1, NULL , 0 );
wchar_t* wstr = new wchar_t[wchars_num];
MultiByteToWideChar( CP_UTF8 , 0 , x.c_str() , -1, wstr , wchars_num );
// do whatever with wstr
delete[] wstr;
另外,请注意使用-1作为
cbMultiByte
参数。这将使生成的字符串以null结尾,从而避免您处理这些字符串。关于这一点的第二个问题,今天早上
WideCharToMultiByte()和MultiByteToWideChar()使用起来很麻烦。每次转换都需要对例程进行两次调用,您必须注意分配/释放内存,并确保字符串正确终止。你需要一个包装
<>我在博客上有一个方便的C++包装,欢迎使用。
这是今天早上的另一个您可以尝试下面的解决方案。我测试了它,它可以工作,可以检测特殊字符(例如:ºäçá),可以在Windows XP、带有SP4的Windows 2000以及更高版本的Windows 7、8、8.1和10上工作。 使用
std::wstring
代替new wchar\u t
/delete
,我们减少了资源泄漏、缓冲区溢出和堆损坏的问题
dwFlags
被设置为MB_ERR_INVALID_CHARS
以在使用SP4的Windows 2000和更高版本的Windows XP上工作。如果未设置此标志,函数将自动删除非法代码点
std::wstring ConvertStringToWstring(const std::string &str)
{
if (str.empty())
{
return std::wstring();
}
int num_chars = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, str.c_str(), str.length(), NULL, 0);
std::wstring wstrTo;
if (num_chars)
{
wstrTo.resize(num_chars);
if (MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, str.c_str(), str.length(), &wstrTo[0], num_chars))
{
return wstrTo;
}
}
return std::wstring();
}
几个常见的转换:
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <string>
std::string ConvertWideToANSI(const std::wstring& wstr)
{
int count = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.length(), NULL, 0, NULL, NULL);
std::string str(count, 0);
WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, &str[0], count, NULL, NULL);
return str;
}
std::wstring ConvertAnsiToWide(const std::string& str)
{
int count = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), NULL, 0);
std::wstring wstr(count, 0);
MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), &wstr[0], count);
return wstr;
}
std::string ConvertWideToUtf8(const std::wstring& wstr)
{
int count = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.length(), NULL, 0, NULL, NULL);
std::string str(count, 0);
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &str[0], count, NULL, NULL);
return str;
}
std::wstring ConvertUtf8ToWide(const std::string& str)
{
int count = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0);
std::wstring wstr(count, 0);
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &wstr[0], count);
return wstr;
}
#定义WIN32_LEAN_和_MEAN
#包括
#包括
std::string ConvertWideToANSI(常量std::wstring&wstr)
{
int count=WideCharToMultiByte(CP_ACP,0,wstr.c_str(),wstr.length(),NULL,0,NULL,NULL);
std::字符串str(计数,0);
WideChartMultiByte(CP_ACP,0,wstr.c_str(),-1,&str[0],count,NULL,NULL);
返回str;
}
std::wstring convertansitowed(const std::string&str)
{
int count=MultiByteToWideChar(CP_ACP,0,str.c_str(),str.length(),NULL,0);
std::wstring wstr(计数,0);
MultiByteToWideChar(CP_ACP,0,str.c_str(),str.length(),&wstr[0],count);
返回wstr;
}
std::string ConvertWideToUtf8(常量std::wstring&wstr)
{
int count=WideCharToMultiByte(CP_UTF8,0,wstr.c_str(),wstr.length(),NULL,0,NULL,NULL);
std::字符串str(计数,0);
WideChartMultiByte(CP_UTF8,0,wstr.c_str(),-1,&str[0],count,NULL,NULL);
返回str;
}
std::wstring ConvertUtf8ToWide(常量std::string&str)
{
int count=MultiByteToWideChar(CP_UTF8,0,str.c_str(),str.length(),NULL,0);
std::wstring wstr(计数,0);
MultiByteToWideChar(CP_UTF8,0,str.c_str(),str.length(),&wstr[0],count);
返回wstr;
}
您不能将指向std::wstring
的指针传递给此函数。+1用于强调需要两次调用MultiByteToWideChar,这对于字符集转换函数是必不可少的。@eranwchar\u t*
和LPTSTR
之间有什么区别?@Suhail Gupta,如果您是用Unicode编译的,那就完全一样了。在多字节构建中,LPTSTR将扩展为常规的char*
。使用这些宏可以创建Unicode和非Unicode版本。不过,我现在想不出有什么理由这么做,因为Unicode现在是VS中的默认值,所以请使用其中任何一个。OWCH!没有免费的东西,即使有,我也不会宽恕这种代码。使用适当调整大小的std::vector
。@DeadMG-Owch确实。。。这就是为什么我说它是粗略的。他很匆忙。修复了答案,谢谢。MultiByteToWideChar
需要类型为wchar\u t*
的参数。Wstring的类型为std::Wstring
——因此无法将其传递给MultiByteToWideChar
(甚至连指向它的指针都没有)。但好消息是,std::wstring
在内部将其数据存储为wchar\u t*
,并提供两个函数来访问此内部数据:data()
(此处使用)和c_str()
@DeadMG,请注意wstring.data()返回常量wchar\u t*,根据cpluplus.com的说法,不应该直接修改(你可能比我更清楚这样做的效果)。OTOH,MBTWC的最后一个参数是0,无论如何都不会在该缓冲区中放置任何东西…@eran:Oops,关于返回值是const
,您完全正确。它不能以这种方式工作,WSString使用32位字符,而win32使用16位unicode字符。。。