2017-08-03 8 views
2

文字列の終端にNULL以外の終了ベクトルがあります。どうすれば新しい文字列を作成し、文字列の末尾に自動的に挿入することができますか?null以外の終了ベクトルを<char>に変換する

std::vector<char> v; 
v.push_back('H'); 
v.push_back('i'); 
v.push_back('!'); 
//v.push_back('\0'); <~ without using this line 

std::string a(v.data()); 
std::string b(v.begin(), v.end()); // same meaning as b(v.data(), v.size()) 

2つの間に正しいコンストラクタはありますか?

+0

'std :: string'を使用している場合、終了するゼロは自動的に処理されます。しかし、 'std :: string'はコピー中にそれを探しているので、' a'のコンストラクタに必要です。 'b'コンストラクタを使うことが最善の方法でしょう – litelite

答えて

7

std::string a(v.data());が正しくありません。コンストラクタは、NULL終了文字シーケンスへのポインタを要求します。それを与えないことは、未定義の振る舞いです。

std::string b(v.begin(), v.end());は完全に安全で、ベクターと同じ内容のstd::stringを提供します。

1

最初の試行は失敗します。 std :: stringはnullで終わる文字配列から構築できますが、null文字がないと、コンストラクタはnullバイトを見つけるまでベクトルが所有していないメモリを読み続けることになります。

あなたの2番目の試みは解決策です。 std:; stringは、イテレータからcharをコピーして、終了するヌル文字を自動的に追加します。

4

このコンストラクタ:

std::string a(v.data()); 

は、引数がnullで終わるCスタイルの文字列の最初の文字へのポインタであることを期待しています。 v.data()はヌルで終了する文字列を指していないため、このコンストラクタ呼び出しには未定義の動作があります。あなたはコンストラクタ呼び出しを有効にするために1つの以上の引数を追加することができ

std::string a(v.data(), v.size()); 

代わりに、このコンストラクタを使用するのでは、次のとおりです。

basic_string(const charT* s, const Allocator& a = Allocator()); 

あなたはこのコンストラクタを使用することもできます。

basic_string(const charT* s, size_type n, const Allocator& a = Allocator()); 

この場合、文字列は正確にv.size()から作成されます。ベクトルに格納されたラクタ。

このコンストラクタ:

std::string b(v.begin(), v.end()); 

が有効であり、かつ実際に以前コンストラクタと比べて、ヌルターミネータない範囲を供給するための別の形態です。

関連する問題