string s = "おはよう";
wstring ws = FUNCTION(s, ws);
s の内容を ws に割り当てるにはどうすればよいですか?
Google を検索し、いくつかの手法を使用しましたが、正確なコンテンツを割り当てることはできません。内容が歪んでいます。
あなたの例(おはよう)の入力文字列が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);
より長いオンラインでコンパイル可能で実行可能な例:
(それらはすべて同じ例を示しています。冗長性のために多くあります...)
注(旧):
コメントで指摘され、https://stackoverflow.com/a/17106065/6345で説明されているように、標準ライブラリを使用して UTF-8 と UTF-16 の間で変換すると、異なるプラットフォームでの結果に予期しない違いが生じる場合があります。 . より良い変換のために、http://en.cppreference.com/w/cpp/locale/codecvt_utf8std::codecvt_utf8
で説明されているように検討してください
注(新規):
ヘッダーは C++17 で廃止されたためcodecvt
、この回答で提示された解決策についていくつかの懸念が提起されました。ただし、C++ 標準委員会はhttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0618r0.htmlに重要な声明を追加しました。
このライブラリ コンポーネントは、適切な代替品が標準化されるまで、 と一緒に附属書 D に廃止する必要があります。
したがって、近い将来、codecvt
この回答のソリューションは安全で移植可能です。
int StringToWString(std::wstring &ws, const std::string &s)
{
std::wstring wsTmp(s.begin(), s.end());
ws = wsTmp;
return 0;
}
あなたの質問は指定不足です。厳密には、その例は構文エラーです。しかし、mbstowcs
おそらくあなたが探しているものです。
これは C ライブラリ関数であり、バッファーで動作しますが、Mooing Duck の厚意による使いやすいイディオムを次に示します。
std::wstring ws(s.size(), L' '); // Overestimate number of code points.
ws.resize(::mbstowcs_s(&ws[0], ws.size(), s.c_str(), s.size())); // Shrink to fit.
から: char*
_wstring
char* str = "hello worlddd";
wstring wstr (str, str+strlen(str));
から: string
_wstring
string str = "hello worlddd";
wstring wstr (str.begin(), str.end());
これは、変換される文字列に ASCII 文字のみが含まれている場合にのみうまく機能することに注意してください。
Boost.Locale の使用:
ws = boost::locale::conv::utf_to_utf<wchar_t>(s);
それのこの変種は、実生活で私のお気に入りです。入力が有効なUTF-8 の場合、入力をそれぞれの に変換しますwstring
。入力が破損している場合、wstring
は 1 バイトから構築されます。これは、入力データの品質について本当に確信が持てない場合に非常に役立ちます。
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;
}
}
ブースト パスまたは標準パスを使用できます。これははるかに簡単です。ブースト パスは、クロスプラットフォーム アプリケーションにとってより簡単です
#include <boost/filesystem/path.hpp>
namespace fs = boost::filesystem;
//s to w
std::string s = "xxx";
auto w = fs::path(s).wstring();
//w to s
std::wstring w = L"xxx";
auto s = fs::path(w).string();
std を使用したい場合:
#include <filesystem>
namespace fs = std::filesystem;
//The same
c++ 旧バージョン
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
//The same
内部のコードは、詳細を解明する必要のないコンバーターをまだ実装しています。
std::string -> wchar_t[]
安全mbstowcs_s
機能付き:
auto ws = std::make_unique<wchar_t[]>(s.size() + 1);
mbstowcs_s(nullptr, ws.get(), s.size() + 1, s.c_str(), s.size());
これは私のサンプルコードからのものです
メソッド 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;
}
私自身のテスト (Windows 8、vs2010) に基づいて、mbstowcs は実際には元の文字列を損傷する可能性があり、ANSI コード ページでのみ機能します。MultiByteToWideChar/WideCharToMultiByte も文字列の破損を引き起こす可能性がありますが、知らない文字を「?」に置き換える傾向があります。疑問符ですが、mbstowcs は不明な文字に遭遇すると停止し、その時点で文字列を切断する傾向があります。(フィンランドのウィンドウでベトナム文字をテストしました)。
そのため、アナログの ansi C 関数よりも Multi*-windows api 関数を優先します。
また、あるコードページから別のコードページに文字列をエンコードする最短の方法に気付いたのは、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 マクロを使用した後 - ASAP を返す方がよいため、スタックは一時的な変換から解放されます。
このコードを使用して、文字列を 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;
}
string s = "おはよう";
はエラーです。
wstring を直接使用する必要があります。
wstring ws = L"おはよう";