web-dev-qa-db-ja.com

char *をwchar_t *に変換する方法は?

このような関数を実装しようとしましたが、残念ながら機能しません:

const wchar_t *GetWC(const char *c)
{
    const size_t cSize = strlen(c)+1;
    wchar_t wc[cSize];
    mbstowcs (wc, c, cSize);

    return wc;
}

ここでの私の主な目標は、Unicodeアプリケーションに通常の文字列を統合できるようにすることです。あなたが提供できるアドバイスは大歓迎です。

48
AutoBotAM

C99可変長配列の代わりにstd::wstringを使用します。現在の標準では、std::basic_stringの連続バッファが保証されています。例えば。、

std::wstring wc( cSize, L'#' );
mbstowcs( &wc[0], c, cSize );

C++はC99可変長配列をサポートしていないため、コードを純粋なC++としてコンパイルした場合、コンパイルすらできません。

この変更により、関数の戻り値の型もstd::wstringになります。

mainに関連するロケールを設定することを忘れないでください。

例:setlocale( LC_ALL, "" )

乾杯

31

あなたの例では、wcは、関数呼び出しが終了したときに割り当て解除されるローカル変数です。これにより、未定義の動作領域になります。

簡単な修正はこれです:

const wchar_t *GetWC(const char *c)
{
    const size_t cSize = strlen(c)+1;
    wchar_t* wc = new wchar_t[cSize];
    mbstowcs (wc, c, cSize);

    return wc;
}

呼び出し元のコードはこのメモリの割り当てを解除する必要があります。そうしないと、メモリリークが発生します。

36
Andrew Shepherd
const char* text_char = "example of mbstowcs";
size_t length = strlen(text_char );

使用例「mbstowcs」

std::wstring text_wchar(length, L'#');

//#pragma warning (disable : 4996)
// Or add to the preprocessor: _CRT_SECURE_NO_WARNINGS
mbstowcs(&text_wchar[0], text_char , length);

使用例「mbstowcs_s」

マイクロソフトでは、「mbstowcs」ではなく「mbstowcs_s」を使用することをお勧めします。

リンク:

Mbstowcsの例

mbstowcs_s、_mbstowcs_s_l

wchar_t text_wchar[30];

mbstowcs_s(&length, text_wchar, text_char, length);
4
Maks

スタックに割り当てられたローカル変数のアドレスを返しています。関数が戻ると、すべてのローカル変数(wcなど)のストレージの割り当てが解除され、すぐに他の何かによって上書きされます。

これを修正するには、バッファのサイズをGetWCに渡すことができますが、mbstowcs自体とほぼ同じインターフェイスを使用できます。または、GetWC内に新しいバッファーを割り当てて、そのポインターを返し、呼び出し元がバッファーの割り当てを解除できるようにします。

2
Greg Hewgill

あなたの問題はエンコーディングとは何の関係もありません。基本的なC++を理解するのは簡単です。関数からローカル変数へのポインターを返しています。これは、誰でも使用できるようになるまでにスコープ外になり、undefined behaviour(つまり、プログラミングエラー)。

このゴールデンルールに従ってください:「裸のcharポインタを使用している場合、あなたはそれを間違っています。(そうでない場合を除いて。)」

以前に投稿された C++ std::stringおよびstd::wstringオブジェクトで変換および入力と出力の通信を行うためのコード。

1
Kerrek SB

私はこのようなことをしました。最初の2つのゼロは、このコマンドが私にどんなASCIIタイプのものを望んでいるかわからないからです。私が持っていた一般的な感覚は、一時文字配列を作成することでした。ワイド文字配列を渡します。ブーム。できます。 +1は、ヌル終端文字が正しい場所にあることを保証します。

char tempFilePath[MAX_PATH] = "I want to convert this to wide chars";

int len = strlen(tempFilePath);

// Converts the path to wide characters
    int needed = MultiByteToWideChar(0, 0, tempFilePath, len + 1, strDestPath, len + 1);
1
Gandalf458