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));
从string
到wstring
:
string str = "hello worlddd"; wstring wstr (str.begin(), str.end());
注意这只有在被转换的string只包含ASCII字符的情况下才有效。
这是一种将string
, wstring
和混合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; }