3

次のように仮定します。

string s("!Hello!'");

私の目的は、s 変数で「Hello」文字列のみを取得することです。感嘆符を削除したい IOW です。

私は次のことを試しました:

std::remove ( s.begin(), s.end(), '!' );

結果の s 文字列を計算すると、次のようになります。

Helloo!

「!」文字は削除されましたが、文字列の末尾は移動されませんでした。

std::remove の戻り値から反復子を取得する必要があることを読みましたが、C++ が初めてで、成功しません。

char::iterator のようなものが有効であると期待していますが、そうではないようです...だから

char::iterator new_end;
new_end = std::remove ( s.begin(), s.end(), '!' );
cout << new_end ;

うまくいきません。

ヘルプ/ポインターをいただければ幸いです。

4

3 に答える 3

9

std::removeコンテナーではなくiteratorで動作します。したがって、コンテナーのサイズを変更することはできません。

erase-remove イディオムを使用する必要があります。

s.erase(std::remove(s.begin(), s.end(), '!'), s.end());

ここでremoveは、削除ロジックを実装し、シーケンス内の新しい最後の要素に反復子を返します。つまり、要素を並べ替えますが、コンテナーには触れません。erase最後に、コンテナの末尾をremove返されたものに設定してコンテナのサイズを変更します。

于 2012-05-21T12:18:13.917 に答える
2

イテレータはコンテナ内の位置を表します。これらは、C の配列要素へのポインターと同様のセマンティクスを持つように設計されています。「終了」イテレーターは、通常、コンテナー内の最後の要素の直後の位置を表します。これは有効なイテレーターですが、逆参照することはできません (使用できないオペレーター)

コンテナから要素を削除するには、remove に続いて erase を使用する必要があります。コレクションから値を削除するために使用できる便利なユーティリティ関数を次に示します。

template<typename Collection, typename Element>
void remove_elements(Collection& c, const Element& e) {
    c.erase(std::remove(c.begin(), c.end(), e), c.end());
};

これで、次のように書くことができます:

remove_elements(s, '!');
于 2012-05-21T12:30:20.387 に答える
0

他の人が解決策を示していますが、Scott Meyer の「なぜ削除しても実際には何も削除されないのか」を確認することをお勧めします(ページの途中のどこか -- ページ全体が興味深い読み物になります、ところで)。

于 2012-05-21T16:45:25.757 に答える