はじめに
文字列から文字を除去するには様々な方法がありますが,ここではC++11で導入されたラムダ式とSTLのremove_if,remove_copy_ifを組み合わせて文字を削除する方法を書き残しておきます.なお,MBCSとかだと扱えなくなるので別の処理が必要だと思います.
C++11やラムダ式を使わない場合はoperator()
を実装する構造体を定義すれば同じことをできます.
remove_ifとremove_copy_if
remove_ifはイテレーターを引数として元のオブジェクトを破壊的に変更します.Rubyで言えばfunction!に該当する関数です.対してremove_copy_ifは元のオブジェクトを破壊せず別のオブジェクトに書き込みを行います.両者の違いはメモリ使用量及び処理速度かと思います.今回は速度についての検証は行いません(既にどこかで行われていると思います).
ソースコード
#include <string> // string #include <algorithm> // remove_if, remove_copy_if #include <iostream> // cout, endl using namespace std; int main() { // 文字列から破壊的に空白を除去する string s1("abc def ghi"); cout << "元の文字列:"<< s1 << endl; auto it = remove_if(s1.begin(), s1.end(), [](const char& c){ return isspace(c); }); cout << "remove_if後の元の文字列:" << s1 << endl; cout << "remove_if後に整形した文字列:" << string(s1.cbegin(), it) << endl; cout << endl; // 文字列から非破壊的に空白を除去する string s2("abc def ghi"); cout << "元の文字列:" << s2 << endl; string s3(s2.length(), 0); // メモリは確保する必要がある auto it2 = remove_copy_if(s2.begin(), s2.end(), s3.begin(), [](const char& c){ return isspace(c); }); cout << "remove_copy_if後の元の文字列:" << s2 << endl; cout << "remove_copy_if後に整形した文字列:" << string(s3.cbegin(), it2) << endl; return 0; }
出力例
元の文字列:abc def ghi remove_if後の元の文字列:abcdefghihi remove_if後に整形した文字列:abcdefghi 元の文字列:abc def ghi remove_copy_if後の元の文字列:abc def ghi remove_copy_if後に整形した文字列:abcdefghi
備考
ラムダ式[](const char& c){ return isspace(c); }
の内部を変更することで任意の文字を削除することができます.例えば,'a'だけを削除するのであれば[](const char& c){ return c == 'a'; }
とします.
boostを使えば文字列単位の置換も簡単に行えるのですね.boostjpのboost::algorithm::replace_allに関する部分を参照です.