C ++将string(或char *)转换为wstring(或wchar_t *)

string s = "おはよう"; wstring ws = FUNCTION(s, ws); 

我如何将s的内容分配给ws?

search谷歌和使用一些技术,但他们不能分配确切的内容。 内容扭曲。

假设你的例子中的inputstring是一个UTF-8编码(它不是,它的外观,但让我们假设它是为了这个解释:-))一个Unicodestring的表示你的兴趣,那么你的问题就可以完全用标准库(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); 

更长的在线可编译和可运行示例:

(他们都显示相同的例子,只有很多冗余…)

注意(旧)

正如在注释中指出的,并在https://stackoverflow.com/a/17106065/6345中解释的,有些情况下使用标准库在UTF-8和UTF-16之间进行转换可能会给不同平台的结果带来意想不到的差异。; 要获得更好的转换,请std::codecvt_utf8 http://en.cppreference.com/w/cpp/locale/codecvt_utf8上的;std::codecvt_utf8

注意(新)

由于codecvt头在C ++ 17中已被弃用,所以有人担心在这个答案中提出的解决scheme。 但是,C ++标准委员会在http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0618r0.html中增加了一个重要的声明;

这个图书馆组成部分应该一并退回附件D,直到适当的替代标准化。

所以在可预见的将来,这个答案中的codecvt解决scheme是安全和便携的。

 int StringToWString(std::wstring &ws, const std::string &s) { std::wstring wsTmp(s.begin(), s.end()); ws = wsTmp; return 0; } 

你的问题是不明确的。 严格来说,这个例子是一个语法错误。 但是, std::mbstowcs可能是你在找什么。

这是一个C库function,并在缓冲区中运行,但是这里有一个易于使用的习惯用法,由TBohne(原Mooing Duck)提供:

 std::wstring ws(s.size(), L' '); // Overestimate number of code points. ws.resize(std::mbstowcs(&ws[0], s.c_str(), s.size())); // Shrink to fit. 

只有Windows API,pre C ++ 11实现,以防有人需要它:

 #include <stdexcept> #include <vector> #include <windows.h> using std::runtime_error; using std::string; using std::vector; using std::wstring; wstring utf8toUtf16(const string & str) { if (str.empty()) return wstring(); size_t charsNeeded = ::MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), NULL, 0); if (charsNeeded == 0) throw runtime_error("Failed converting UTF-8 string to UTF-16"); vector<wchar_t> buffer(charsNeeded); int charsConverted = ::MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), &buffer[0], buffer.size()); if (charsConverted == 0) throw runtime_error("Failed converting UTF-8 string to UTF-16"); return wstring(&buffer[0], charsConverted); } 

如果您使用的是Windows / Visual Studio,并且需要将string转换为wstring,则可以使用:

 #include <AtlBase.h> #include <atlconv.h> ... string s = "some string"; CA2W ca2w(s.c_str()); wstring w = ca2w; printf("%s = %ls", s.c_str(), w.c_str()); 

将wstring转换为string的相同过程(有时您需要指定一个代码页 ):

 #include <AtlBase.h> #include <atlconv.h> ... wstring w = L"some wstring"; CW2A cw2a(w.c_str()); string s = cw2a; printf("%s = %ls", s.c_str(), w.c_str()); 

你可以指定一个代码页 ,甚至UTF8(使用JNI / Java时,这是相当不错的)。

 CA2W ca2w(str, CP_UTF8); 

如果您想了解更多关于代码页的信息 ,可以参阅关于Joel on Software的一篇有趣的文章: 绝对最小化每个软件开发人员绝对肯定必须了解Unicode和字符集 。

这些CA2W(将Ansi转换为Wide = unicode)macros是ATL和MFCstring转换macros的一部分 ,包括样本。

有时你需要禁用安全警告#4995',我不知道其他解决方法(对于我在VS2012中编译WindowsXp时发生的)。

 #pragma warning(push) #pragma warning(disable: 4995) #include <AtlBase.h> #include <atlconv.h> #pragma warning(pop) 

编辑:好吧,根据这篇文章,Joel的文章似乎是:“而娱乐,实际技术细节上很轻。 文章: 每个程序员绝对,积极需要知道编码和字符集与文本工作 。

char*wstring

 char* str = "hello worlddd"; wstring wstr (str, str+strlen(str)); 

stringwstring

 string str = "hello worlddd"; wstring wstr (str.begin(), str.end()); 

注意这只有在被转换的string只包含ASCII字符的情况下才有效。

这是一种将stringwstring和混合string常量组合到wstring 。 使用wstringstream类。

 #include <sstream> std::string narrow = "narrow"; std::wstring wide = "wide"; std::wstringstream cls; cls << " abc " << narrow.c_str() << L" def " << wide.c_str(); std::wstring total= cls.str(); 

使用Boost.Locale:

 ws = boost::locale::conv::utf_to_utf<wchar_t>(s); 

它的这个变体是我在现实生活中的最爱。 它将input( 如果它是有效的 UTF-8)转换为相应的wstring 。 如果input被破坏,那么wstring是由单个字节构成的。 如果您无法确定input数据的质量,这非常有用。

 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; } } 

基于我自己的testing(在Windows 8,vs2010)mbstowcs实际上可能会损坏原始string,它只适用于ANSI代码页。 如果MultiByteToWideChar / WideCharToMultiByte也可能导致string损坏 – 但它们倾向于用'?'来replace他们不知道的字符。 问号,但是当遇到未知的字符和切断string时,mbstowcs往往停止。 (我在芬兰的窗户上testing过越南文字)。

所以,喜欢Multi * -windows API函数,而不是模拟ansi C函数。

另外我注意到,从一个代码页到另一个代码string的最短编码方式不是使用MultiByteToWideChar / WideCharToMultiByte api函数调用,而是使用模拟ATLmacros:W2A / A2W。

所以上面提到的模拟function听起来像:

 wstring utf8toUtf16(const string & str) { USES_CONVERSION; _acp = CP_UTF8; return A2W( str.c_str() ); } 

在USES_CONVERSIONmacros中声明_acp。

或者,当执行旧的数据转换到新的时候,我经常会错过的function:

 string ansi2utf8( const string& s ) { USES_CONVERSION; _acp = CP_ACP; wchar_t* pw = A2W( s.c_str() ); _acp = CP_UTF8; return W2A( pw ); } 

但请注意,这些macros的使用大量堆栈 – 不要使用for循环或recursion循环相同的function – 使用W2A或A2Wmacros后 – 更好地返回ASAP,所以堆栈将从临时转换释放。

方法s2ws运作良好。 希望有帮助。

 std::wstring s2ws(const std::string& s) { std::string curLocale = setlocale(LC_ALL, ""); const char* _Source = s.c_str(); size_t _Dsize = mbstowcs(NULL, _Source, 0) + 1; wchar_t *_Dest = new wchar_t[_Dsize]; wmemset(_Dest, 0, _Dsize); mbstowcs(_Dest,_Source,_Dsize); std::wstring result = _Dest; delete []_Dest; setlocale(LC_ALL, curLocale.c_str()); return result; } 

string s = "おはよう"; 是一个错误。

你应该直接使用wstring:

 wstring ws = L"おはよう"; 

使用此代码将您的string转换为wstring

 std::wstring string2wString(const std::string& s){ int len; int slength = (int)s.length() + 1; len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); wchar_t* buf = new wchar_t[len]; MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len); std::wstring r(buf); delete[] buf; return r; } int main(){ std::wstring str="your string"; std::wstring wStr=string2wString(str); return 0; }