2013-09-05 6 views
5

私は、数字だけを含む入力文字列を持っています(平文のラテン文字、0-9、したがって "0123"など)、std :: wstringとして格納されていますそれぞれがchar *として扱われます。これを行うための最善の方法は何ですか?これは私の初期のアプローチです:std :: wstingをchar *にwcstombs_sで変換する

void type::convertWStringToCharPtr(_In_ std::wstring input, _Out_ char * outputString) 
{ 
    outputString = new char[outputSize]; 
    size_t charsConverted = 0; 
    const wchar_t * inputW = input.c_str(); 
    wcstombs_s(&charsConverted, outputString, sizeof(outputString), inputW, input.length()); 
} 

編集:以下のコードは動作します。皆さんありがとう!

void type::convertWStringToCharPtr(_In_ std::wstring input, _Out_ char * outputString) 
{ 
    size_t outputSize = input.length() + 1; // +1 for null terminator 
    outputString = new char[outputSize]; 
    size_t charsConverted = 0; 
    const wchar_t * inputW = input.c_str(); 
    wcstombs_s(&charsConverted, outputString, outputSize, inputW, input.length()); 
} 
+2

はsizeof(outputstring)doesntのは、uはそれがないと思う何をすべきか。ポインタがどれくらい大きいのかを教えてください – pm100

+0

ありがとう、私はコードを更新しました。私はwcstombs_sが何らかの理由でポインタのサイズを望んだと思った。 –

+0

まだ動作していませんか? –

答えて

10

あなたのバッファのための十分なメモリを割り当てていません。

char * outputString = new char[input.length()]; 

が原因NUL文字を終了する

char * outputString = new char[input.length() + 1]; 

である必要があります。

ああ、また、pm100のコメント:sizeof(outputString)はあなたにポインタのサイズを与えています。バッファのサイズであるinput.length() + 1を使用する必要があります。

5

コードにいくつかのエラーがあります。まず、NULL文字のために、宛先バッファに十分な領域を割り当てていません。関数を成功させるには、少なくともinput.length() + 1の文字を割り当てる必要があります。

第2に、正しいサイズの出力バッファを関数に渡していません。 sizeof(outputString)は、outputString自体のサイズ、つまりchar *を返します。ポインタで指されたバイト数ではありません。

だからあなたの関数は次のようになります。私は純粋なポインタを使用することはないC++では

void CoverageTileManager::convertWStringToCharPtr(_In_ std::wstring input, _Out_ char * outputString) 
{ 
    size_t outputSize = input.length() + 1; 
    outputString = new char[outputSize]; 
    size_t charsConverted = 0; 
    wcstombs_s(&charsConverted, outputString, outputSize, input.c_str(), input.length()); 
    // TODO verify charsConverted = outputSize 
} 
1

:char配列はヒープに必要であればvectorを使用!ソース文字列をコピーしますか?そうでない場合は、inputにconst参照を使用する必要があります。 wcstombs_sはWindowsでのみ使用されるため、なぜ単純にWideCharToMultiByteを使用しないのですか?変換は成功しましたか?戻り値外部のC++のlibに

bool CoverageTileManager::convertWStringToCharPtr(const std::wstring& input, std::vector<char>& outputString) 
{ 
    if (input.empty()) { 
     return false; 
    } 
    int size = WideCharToMultiByte(CP_ACP,0,input.c_str(),input.size(),NULL,0,NULL,NULL); 
    if (size <= 0) { 
     return false; 
    } 
    outputString.resize(size+1); 
    if (WideCharToMultiByte(CP_ACP,0,input.c_str(),input.size(),&outputString[0],size,NULL,NULL) <= 0) { 
     outputString.clear(); 
     return false; 
    } 
    outputString[size] = '\0'; 
    return true; 
} 

使用ベクトル:

extern void call(const char*, size_t); 
std::vector<char> buffer; 
std::wstring input; 
... 
if (convertWStringToCharPtr(input,buffer)) { 
    call(&buffer[0],buffer.size()); 
} 
+0

私はchar *型の選択肢がありません - それは私が立ち往生している外部ライブラリが必要です。もし私の方法を持っていれば、それはやっている作業のための完全に可能なタイプのstd :: wstringを取るだけで、変換は必要ありません。 –

+0

@ fatcat1111:私はこのデザインを信じることができません: 'wstring'を取得し、Cスタイルの文字列をターゲットとして使用します。奇妙な。あなたがいない! :) – Naszta

+0

@ fatcat1111:ベクトルはCまたはC++関数の外部で使用できます。 – Naszta