web-dev-qa-db-ja.com

C ++ std :: transform()およびtoupper()..なぜこれが失敗するのですか?

2つのstd :: stringがあります。入力文字列を指定して、次のようにします。

  1. すべての文字を大文字にする
  2. 大文字を出力文字列に割り当てます。

なぜこれが機能するのですか?

  std::string s="hello";
  std::string out;
  std::transform(s.begin(), s.end(), std::back_inserter(out), std::toupper);

しかし、これはそうではありません(プログラムがクラッシュします)?

  std::string s="hello";
  std::string out;
  std::transform(s.begin(), s.end(), out.begin(), std::toupper);

これは機能するためです(少なくとも同じ文字列では:

  std::string s="hello";
  std::string out;
  std::transform(s.begin(), s.end(), s.begin(), std::toupper);
29
sivabudh

outにはスペースがありません。 C++アルゴリズムは、ターゲットコンテナを自動的に拡張しません。自分でスペースを作るか、インサーターアダプターを使用する必要があります。

outにスペースを作成するには、次のようにします。

out.resize(s.length());

[編集]別のオプションは、このコンストラクターを使用して正しいサイズの出力文字列を作成することです。

std::string out(s.length(), 'X');

43
hrnt

out.begin()によって返されるイテレータは、空の文字列を2、3インクリメントした後は無効だと思います。最初の_++_の後は==out.end()であり、次の増分後の動作は未定義です。

結局のところ、これはまさに挿入イテレータの目的です。

それはバックインサーターの意味です:それは挿入要素をコンテナーに入れます。 begin()を使用して、イテレータを空のコンテナに渡し、無効なイテレータを変更します。

申し訳ありませんが、私の編集があなたのコメントに干渉しました。私は最初に誤って何か間違ったものを投稿しました。

0
RED SOFT ADAIR