2011-07-14 35 views
11

通常のstringwide stringに変換したいとします。このため私は関数MultiByteToWideCharを使用しています。 しかし、私はこの機能を使って成功していません。ここまでは私が今まで何をしているのですか?MultiByteToWideCharを使用した場合の問題

string x = "This is c++ not java"; 
wstring Wstring; 
int c = MultiByteToWideChar(CP_UTF8 , 0 , x.c_str() , x.size() , &Wstring , 0); 
// The above line produces error which says 'MultiByteToWideChar' : cannot convert parameter 5 from 'std::wstring *' to 'LPWSTR' 

どのように私はこのエラーを修正することができますか?そして、この関数のの第6の引数は何ですか? 0は大丈夫ですか?

+1

この関数に 'std :: wstring'へのポインタを渡すことはできません。 –

答えて

26

MultiByteToWideCharの最後のパラメータが0の場合は、その前にNULLを渡す必要があります。 doc

この値が0の場合、関数は必要なバッファサイズを任意の終端ヌル文字を含めて文字で返し、lpWideCharStrバッファを使用しません。

最初にMultiByteToWideCharを呼び出すと、ワイド文字列に必要なバッファのサイズが返されます。次に、ワイド文字列に対応できる大きさの非constバッファを取得し、別の呼び出しでMultiByteToWideCharに渡す必要があります(このとき、最後の引数はバッファの実際のサイズであり、0ではありません)。

scetchy例:また

int wchars_num = MultiByteToWideChar(CP_UTF8 , 0 , x.c_str() , -1, NULL , 0); 
wchar_t* wstr = new wchar_t[wchars_num]; 
MultiByteToWideChar(CP_UTF8 , 0 , x.c_str() , -1, wstr , wchars_num); 
// do whatever with wstr 
delete[] wstr; 

は、cbMultiByte引数として-1の使用を注意してください - それは、終端のNULLを扱う必要がなくなります。

+1

+1 MultiByteToWideCharを2回呼び出す必要があることを強調するために、これはcharset変換関数にとって不可欠です。 – Stephan

+0

@ eran 'wchar_t *と' LPTSTR'の違いは何ですか? –

+0

@Suhail Gupta、あなたがUnicodeでコンパイルしているのなら、まったく同じです。マルチバイトビルドでは、LPTSTRは通常の 'char *'に展開されます。これらのマクロを使用すると、Unicodeビルドと非Unicodeビルドの両方を作成できます。私は最近、その理由を考えることはできません。ユニコードはVSのデフォルトになっているので、どちらか一方を使用してください。 – eran

0

この関数は、C++文字列へのポインタを取ることはできません。十分なサイズのワイド文字のバッファへのポインタが必要です。このバッファを自分で割り当てる必要があります。

string x = "This is c++ not java"; 
wstring Wstring; 
Wstring.resize(x.size()); 
int c = MultiByteToWideChar(CP_UTF8 , 0 , x.c_str() , x.size() , &Wstring[0], 0); 
+0

あなたがしたことを詳しく教えていただけますか? –

+1

'MultiByteToWideChar'は' wchar_t * '型のパラメータを要求します。 Wstringは 'std :: wstring'型なので、' MultiByteToWideChar'(それを指すポインタさえも)に渡すことはできません。しかし、良いことは、 'std :: wstring'は内部的にデータを' wchar_t * 'として保存し、この内部データにアクセスするための関数 'data()'と 'c_str() '。 – Stephan

+1

@DeadMG、wstring.data()はconst wchar_t *を返します。これはcplusplus.comへの帰属を直接変更するべきではないことに注意してください。 OTOH、MBTWCの最後の引数が0の場合、何もそのバッファに何も配置されません... – eran

1

これについての2番目の質問、今朝!

WideCharToMultiByte()およびMultiByteToWideChar()は、使用する苦痛です。それぞれの変換ではルーチンへの呼び出しが2回必要で、メモリの割り当て/解放と文字列が正しく終了していることを確認する必要があります。あなたはラッパーが必要です!

私は便利なC++ラッパーをブログのhereに入れておきます。

ここで他のquestion今朝

0

は、あなたが以下このソリューションを試すことができます。 Windows XP、Windows 2000(SP4以降)、Windows 7,8、8.1、および10で動作します。 std::wstringの代わりにnew wchar_t/deleteを使用すると、問題が軽減されますリークリソース、オーバーフローバッファ、破損したヒープ。

dwFlagsMB_ERR_INVALID_CHARSに設定すると、Windows 2000 SP4以降、Windows XPで動作します。このフラグが設定されていない場合、この関数は不正なコードポイントを静かに削除します。

std::wstring ConvertStringToWstring(const std::string &str) 
{ 
    if (str.empty()) 
    { 
     return std::wstring(); 
    } 
    int num_chars = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, str.c_str(), str.length(), NULL, 0); 
    std::wstring wstrTo; 
    if (num_chars) 
    { 
     wstrTo.resize(num_chars); 
     if (MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, str.c_str(), str.length(), &wstrTo[0], num_chars)) 
     { 
      return wstrTo; 
     } 
    } 
    return std::wstring(); 
} 
関連する問題