142


70

C ++文字列(またはchar *)をwstring(またはwchar_t *)に変換
string s = "おはよう";
wstring ws = FUNCTION(s, ws);

sのコンテンツをwsにどのように割り当てますか?

グーグルを検索し、いくつかのテクニックを使用しましたが、正確なコンテンツを割り当てることができません。 コンテンツがゆがんでいます。

13 Answer


201


あなたの例の入力文字列(おはよう)はUTF-8でエンコードされていると仮定します(見た目ではそうではありませんが、この説明のためだと仮定しましょう:-))Unicode文字列の表現興味のある場合は、標準ライブラリ(C ++ 11以降)だけで問題を完全に解決できます。

  • TL; DRバージョン:*

#include
#include
#include

std::wstring_convert> 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_utf8で説明されているように `std

codecvt_utf8`を考慮してください

注(新規)

`codecvt`ヘッダーはC 17で非推奨になったため、この回答で示された解決策についてのいくつかの懸念が提起されました。 ただし、C 標準委員会はhttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0618r0.htmlに次のような重要な声明を追加しました。

_ 適切な代替品が標準化されるまで、このライブラリコンポーネントはとともに、付録Dで廃止する必要があります。 _

したがって、近い将来、この回答の「codecvt」ソリューションは安全で移植性があります。


42


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

    ws = wsTmp;

    return 0;
}


28


あなたの質問は未指定です。 厳密には、その例は構文エラーです。 ただし、http://en.cppreference.com/w/cpp/string/multibyte/mbstowcs [`std

mbstowcs`]がおそらく探しているものです。

これはCライブラリ関数であり、バッファで動作しますが、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.


16


誰かがそれを必要とする場合に備えて、Windows APIのみ、C ++ 11より前の実装:

#include
#include
#include

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


12


_Windows _ / _ Visual Studio_を使用していて、文字列をwstringに変換する必要がある場合は、次を使用できます。

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

wstringを文字列に変換するための同じ手順(_codepage_を指定する必要がある場合があります):

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

_codepage_とUTF8を指定することもできます(_JNI _ / _ Java_を使用する場合は非常に便利です)。

CA2W ca2w(str, CP_UTF8);

_codepages_の詳細を知りたい場合は、ソフトウェアに関するJoelの興味深い記事があります。http://www.joelonsoftware.com/articles/Unicode.html ]。

これらのCA2W(ANSIをWide = unicodeに変換)マクロは、http://msdn.microsoft.com/en-us/library/87zae4a3.aspx [ATLおよびMFC文字列変換マクロ]の一部であり、サンプルが含まれています。

セキュリティ警告#4995 'を無効にする必要がある場合がありますが、他の回避策はわかりません(VS2012でWindowsXp用にコンパイルしたときに発生します)。

#pragma warning(push)
#pragma warning(disable: 4995)
#include
#include
#pragma warning(pop)

*編集:*さて、http://kunststube.net/encoding/ [この記事]によると、Joelの記事は次のように見えます。 記事:http://kunststube.net/encoding/ [すべてのプログラマーが、テキストを処理するためにエンコーディングと文字セットについて絶対に知る必要があること]。


10


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


10


以下は、「string」、「wstring」、および混合ストリング定数を「wstring」に結合する方法です。 `wstringstream`クラスを使用します。

#include

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


6


Boost.Localeを使用:

ws = boost::locale::conv::utf_to_utf(s);


3


それのこのバリアントは、実際の生活で私のお気に入りです。 入力(有効な場合)UTF-8をそれぞれの「wstring」に変換します。 入力が破損している場合、 `wstring`は単一バイトから構築されます。 これは、入力データの品質を本当に確認できない場合に非常に役立ちます。

std::wstring convert(const std::string& input)
{
    try
    {
        std::wstring_convert> 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;
    }
}


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