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

s の内容を ws に割り当てるにはどうすればよいですか?

Google を検索し、いくつかの手法を使用しましたが、正確なコンテンツを割り当てることはできません。内容が歪んでいます。

4

19 に答える 19

275

あなたの例(おはよう)の入力文字列が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この回答のソリューションは安全で移植可能です。

于 2013-09-03T16:39:48.520 に答える
59
int StringToWString(std::wstring &ws, const std::string &s)
{
    std::wstring wsTmp(s.begin(), s.end());

    ws = wsTmp;

    return 0;
}
于 2012-01-23T09:54:13.157 に答える
38

あなたの質問は指定不足です。厳密には、その例は構文エラーです。しかし、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.
于 2010-04-04T07:42:29.133 に答える
13

から: 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 文字のみが含まれている場合にのみうまく機能することに注意してください。

于 2013-03-05T16:10:47.833 に答える
9

Boost.Locale の使用:

ws = boost::locale::conv::utf_to_utf<wchar_t>(s);
于 2015-09-21T09:42:31.620 に答える
8

それのこの変種は、実生活で私のお気に入りです。入力が有効な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;
    }
}
于 2016-08-18T12:33:38.697 に答える
4

ブースト パスまたは標準パスを使用できます。これははるかに簡単です。ブースト パスは、クロスプラットフォーム アプリケーションにとってより簡単です

#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

内部のコードは、詳細を解明する必要のないコンバーターをまだ実装しています。

于 2021-06-08T04:55:34.010 に答える
2

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());

これは私のサンプルコードからのものです

于 2020-08-21T09:18:11.600 に答える
1

メソッド 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;
}
于 2013-09-03T15:57:04.703 に答える
1

私自身のテスト (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 を返す方がよいため、スタックは一時的な変換から解放されます。

于 2015-10-26T21:06:51.590 に答える
-1

このコードを使用して、文字列を 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;
}
于 2015-04-08T11:48:38.283 に答える
-3

string s = "おはよう";はエラーです。

wstring を直接使用する必要があります。

wstring ws = L"おはよう";
于 2010-04-04T07:45:08.027 に答える