2017-02-27 5 views
2

これはHow to convert a vector<char*> to a vector<string>/stringの反対です。ベクトル<string>をベクトルに変換する方法<char*>

私はvector<char*>で動作するいくつかのレガシールーチンを持っていますので、vector<string>を変換する必要があります。ここで

は、私が出てくるものです:

std::vector<char*> charVec(strVec.size(),nullptr); 
for (int i=0; i<strVec.size();i++) { 
    charVec[i]= new char(strVec[i].size()+1); 
    charVec[i][strVec[i].copy(charVec[i], strVec[i].size())] = '\0'; 
} 

は、この正しいですか?

これを実装するより良い方法はありますか?


p.s.もちろん最後に私が持っている:

for (int i=0; i<strVec.size();i++) { 
    delete charVec[i]; 
} 
+0

あなたの質問は何ですか? –

+1

質問がありますか?すでに実装されているようです。 – vu1p3n0x

+1

新しいベクターがその文字列を所有する必要があるか、または他のベクターの文字列の一時的な表示が必要かどうかによって異なります。 – Galik

答えて

6

これを行うためのより高速な方法は

std::vector<const char*> charVec(strVec.size(),nullptr); 
for (int i=0; i<strVec.size();i++) { 
    charVec[i]= strVec[i].c_str(); 
} 

、その後、得られたベクターを使用しています。これにより、大きなデータセットのメモリ割り当てに多くの時間が節約されます。

+0

あなたの結果ベクトルは 'std :: vector 'である必要があります。 'const char *'は 'char *'に割り当てられません – MRB

+0

ありがとう、私は私の答えを修正しました。私はいつもc_strがconstポインタを返すことを忘れています。 – JeremiahB

2

あなたは単にのstd ::文字列から文字列を取得するためにstring::c_str()を使用することができます。 How to convert a std::string to const char* or char*?

また、関数の本体をちょっと修正することもできますが、これが価値があるかどうかだけ知ることができます。


もちろん、コメントにssellが記載されているので、この方法では文字列を処理する際に文字列を破壊する必要はありません。それはトレードオフですが、あなたはコピーを避けるので(涼しい)、迷惑メールを読まないように注意する必要があります(あなたの文字列を削除する場合に備えて)!

+0

'std :: string :: c_str'は安全ではないのでお勧めしません。元の 'std :: string'オブジェクトが破壊された場合、' char * '文字列は無効になります。彼が質問にしているようにデータをコピーし、他の人が答えをするのが良いです。 [std :: string :: c_str()とは何ですか?](http://stackoverflow.com/questions/6456359/what-is-stdstringc-str-lifetime)を参照してください。 – ssell

+0

@ssell良い点ですが、私は "触れないでください"という指示には行かないでしょう、もっと注意して使用したいと思います、私は更新します! – gsamaras

+1

彼が範囲を厳密に管理しているなら、あなたの答えは最も単純です。潜在的な危険性について警告するだけでした。 – ssell

3

なぜあなたの文字列に新しいバッファを割り当てていますか?関数への文字ポインタのvectorを渡し、最後に割り当てられたバッファを削除しています。これは、これらのバッファが一時的であり、ソースvectorvector<string>)が存在する限り、メモリを割り当てる必要はないことを意味します。

あなたは簡単にこれを行うことができます。

std::vector<std::string> vec1 = { "1", "2", "3" }; 
std::vector<const char*> vec2; 

vec2.resize(vec1.size(), nullptr); 

std::transform(std::begin(vec1), std::end(vec1), std::begin(vec2), [&](const std::string& str) 
{ 
    return str.c_str(); 
}); 
+0

また、 'vec2.resize()'を 'vec2.reserve()'に置き換え、 'std :: back_inserter(vec2)'を出力イテレータとして使うこともできます。 –

+0

@RemyLebeauもちろん、良い点。 'std :: back_inserter'を忘れてしまった。思い出してくれてありがとう。 – MRB

3

あなたnew文は間違って見えます。文字列を保持するのに十分な長さのcharの配列を割り当てたいとします。文字列の長さを値とする単一のcharを割り当てています。私はあなたがそれについてコンパイラの警告を受け取っていないのに驚いています。

はこれを試してみてください:ここ

std::vector<char*> charVec; 
for (const auto &str : strVec) { 
    char *charStr = new char[str.size() + 1]; 
    std::strcpy(charStr, str.c_str()); 
    charVec.push_back(charStr); 
} 

唯一の欠点は、文字列のいずれかがnull文字が埋め込まれている場合は、それらを越えて何もコピーされません、ということです。しかし、私は、char *のベクトルをとる関数は、とにかくそれについてはほとんど気にしないと思う。

関連する問題