String Algorithm

プログラムを書いていると,ちょっとした文字列操作が必要になる場合が多々あるのですが,C++だと若干の不便さを感じます.Boostを使っても良いのですが,せっかくなので一通りの文字列操作関数を記述してみました.実装する機能および関数名は,Rubyを参考にしました(一部,異なるものもありますが).機能ごとにできるだけ1ファイルで収まるように記述したので,該当のヘッダファイル(+ predicate.h)をコピーするだけと言う手軽さが嬉しいときもあるかな,と.

以下に,実装した機能の宣言一覧を列挙.基本的には,xxx_copy(),xxx_if(),xxx_copy_if()という関数も同時に定義してあります.また,template < ... >の部分は省略しましたが,単語の先頭が大文字になっているものはテンプレート引数として渡される型です(ただし,Stringはstd::basic_string<CharT, Traits>という形になっています).

adjust.h

String& ljust(String& s, unsigned int n, CharT c = ' ');
String& rjust(String& s, unsigned int n, CharT c = ' ');
String& center(String& s, unsigned int n, CharT c = ' ');

それぞれ,文字列を左詰め,右詰め,センタリングして,余白を指定された文字で埋めます.これらの関数には,xxx_copy(),xxx_if(),xxx_copy_if()という関数は存在しません.

case_conv.h

String& upcase(String& s, const std::locale& loc = std::locale());
String& downcase(String& s, const std::locale& loc = std::locale());
String& swapcase(String& s, const std::locale& loc = std::locale());
String& capitalize(String& s, const std::locale& loc = std::locale());

upcase,downcaseは,文字列中のアルファベットをそれぞれ,大文字,小文字にします.swapcaseは,大文字は小文字に,小文字は大文字に変換します.capitalizeは,文字列中の先頭の文字を大文字に変換します.

remove.h

String& remove(String& s, CharT c);
String& unique(String& s);
String& squeeze(String& s, CharT c);

remove,およびuniqueは,それぞれSTL Algorithmで定義されているstd::remove,std::uniqueのラッパ関数です.STL Algorithmでは,文字列を実際には消去しないため後処理まで行うようにしています(参考:Standard Template Library プログラミング on the Web:アルゴリズム(Algorithm)).uniqueは,文字列中において連続している全ての文字を一文字にします.これに対してsqueezeは,文字列中において連続している文字cを一文字にします.

replace.h

String& replace(String& s, const String& sch, const String& rep,
    unsigned int nth = 1);
String& replace(String& s, const CharT* sch, const CharT* rep,
    unsigned int nth = 1);
String& replace_all(String& s, const String& sch, const String& rep);
String& replace_all(String& s, const CharT* sch, const CharT* rep);

replaceは,文字列中に存在するnth番目の文字列schを文字列repに置換します.これに対してreplace_allは,文字列中に存在する全ての文字列schを文字列repに置換します.これらの関数には,xxx_copy(),xxx_if(),xxx_copy_if()という関数は存在しません.尚,文字列中におけるある文字を別の文字で置き換える操作についてはSTL Algorithmを使用します.

std::replace_if(s.begin(), s.end(), std::bind2nd(std::equal_to<CharT>(), sch), rep)

split.h

Container& split(const String& s, Container& result,
    bool x = false, const std::locale& loc = std::locale());
String& join(const Container& v, String& result, const String& delim);
String& join(const Container& v, String& result, const CharT* delim);

splitは,空白文字を区切り文字として文字列を分割し,結果をContainerに格納します.そのため,Containerにはstd::vector<String>など,分割した文字列を格納できるものを渡す必要があります.joinはその逆関数であり,Containerに格納されている文字列群を文字列delimを区切り文字として結合し,一つの文字列にします.splitには,split_copy(),split_copy_if()が,joinには,join_copy(),join_if(),join_copy_if()が存在しません.

strip.h

String& lstrip(String& s, const std::locale& loc = std::locale());
String& rstrip(String& s, const std::locale& loc = std::locale());
String& strip(String& s, const std::locale& loc = std::locale());
String& chop(String& s);
String& chomp(String& s);

stripは,文字列の前後に存在する空白文字を除去します.lstrip,rstripはそれぞれ,文字列の先頭,末尾に存在する空白文字を除去します.chopは,末尾の文字を1文字除去し,chompは,末尾の改行文字を除去します.