string s = "おはよう";
wstring ws = FUNCTION(s, ws);
如何将s的内容分配给ws?
搜索谷歌并使用了一些技术,但他们不能分配确切的内容。内容被扭曲了。
string s = "おはよう";
wstring ws = FUNCTION(s, ws);
如何将s的内容分配给ws?
搜索谷歌并使用了一些技术,但他们不能分配确切的内容。内容被扭曲了。
当前回答
根据我自己的测试(在windows 8上,vs2010) mbstowcs实际上可以破坏原始字符串,它只适用于ANSI代码页。If MultiByteToWideChar/WideCharToMultiByte也会导致字符串损坏-但他们倾向于用'?'问号,但mbstowcs往往会在遇到未知字符时停止,并在此时切断字符串。(我在芬兰语窗口上测试过越南字符)。
所以更喜欢Multi* windows api函数而不是模拟ansi C函数。
我还注意到,从一个代码页到另一个代码页编码字符串的最短方法不是使用MultiByteToWideChar/WideCharToMultiByte api函数调用,而是它们的模拟ATL宏:W2A / A2W。
所以如上所述的模拟函数听起来是这样的:
wstring utf8toUtf16(const string & str)
{
USES_CONVERSION;
_acp = CP_UTF8;
return A2W( str.c_str() );
}
_acp在USES_CONVERSION宏中声明。
或者在执行旧数据到新数据的转换时,我经常错过的函数:
string ansi2utf8( const string& s )
{
USES_CONVERSION;
_acp = CP_ACP;
wchar_t* pw = A2W( s.c_str() );
_acp = CP_UTF8;
return W2A( pw );
}
但请注意,这些宏使用大量的堆栈-不要为同一个函数使用for循环或递归循环-在使用W2A或A2W宏后-最好尽快返回,因此堆栈将从临时转换中释放出来。
其他回答
int StringToWString(std::wstring &ws, const std::string &s)
{
std::wstring wsTmp(s.begin(), s.end());
ws = wsTmp;
return 0;
}
这是我的超级基本解决方案,可能并不适用于所有人。但对很多人都适用。
它需要使用指南支持库。 这是一个非常官方的c++库,由许多c++委员会的作者设计:
https://github.com/isocpp/CppCoreGuidelines https://github.com/Microsoft/GSL
std::string to_string(std::wstring const & wStr)
{
std::string temp = {};
for (wchar_t const & wCh : wStr)
{
// If the string can't be converted gsl::narrow will throw
temp.push_back(gsl::narrow<char>(wCh));
}
return temp;
}
我的函数所做的只是允许转换。否则抛出异常。
通过使用gsl::narrow (https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es49-if-you-must-use-a-cast-use-a-named-cast)
这个版本是我在现实生活中最喜欢的。它将输入(如果它是有效的UTF-8)转换为相应的wstring。如果输入损坏,则用单个字节构造wstring。如果您不能真正确定输入数据的质量,这是非常有用的。
std::wstring convert(const std::string& input)
{
try
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
return converter.from_bytes(input);
}
catch(std::range_error& e)
{
size_t length = input.length();
std::wstring result;
result.reserve(length);
for(size_t i = 0; i < length; i++)
{
result.push_back(input[i] & 0xFF);
}
return result;
}
}
使用Boost。地区:
ws = boost::locale::conv::utf_to_utf<wchar_t>(s);
假设您的示例(おはよう)中的输入字符串是UTF-8编码的(从表面上看,它不是,但为了解释起见,让我们假设它是您感兴趣的Unicode字符串的表示形式:-),那么您的问题可以仅通过标准库(c++ 11或更新版本)完全解决。
TL;DR版本:
#include <locale>
#include <codecvt>
#include <string>
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::string narrow = converter.to_bytes(wide_utf16_source_string);
std::wstring wide = converter.from_bytes(narrow_utf8_source_string);
更长的在线可编译和可运行的示例:
(它们都展示了相同的例子。只是有很多冗余……)
http://ideone.com/KA1oty http://ide.geeksforgeeks.org/5pRLSh http://rextester.com/DIJZK52174
备注(旧):
正如评论中指出并在https://stackoverflow.com/a/17106065/6345中解释的那样,在使用标准库在UTF-8和UTF-16之间进行转换时,在不同的平台上可能会产生意想不到的结果差异。为了更好的转换,请考虑http://en.cppreference.com/w/cpp/locale/codecvt_utf8上描述的std::codecvt_utf8
备注(新):
由于codecvt头文件在c++ 17中已弃用,因此有人对这个答案中提出的解决方案提出了一些担忧。然而,c++标准委员会在http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0618r0.html中增加了一项重要声明
这个库组件应该退役到附件D中,直到一个合适的替换被标准化。
所以在可预见的未来,这个答案中的codecvt解决方案是安全的和可移植的。