ユーティリティ関数
POCOには、Unicode関連以外にも、汎用的に使えるような関数がいくつか定義されています。その中のテキスト処理に関するものを以下にまとめました。
string補助クラス
POCOでは、std::stringに代わるような独自の文字列クラスは用意されていません。通常は、std::stringを利用することになりますが、std::stringの機能を補うための関数が用意されています。
関数名 | 概要 |
trim | 文字列の先頭と末尾のホワイトスペース除去 |
trimInPlace | 文字列の先頭と末尾のホワイトスペース除去(元の文字列を更新) |
trimLeft | 文字列の先頭のホワイトスペース除去 |
trimRight | 文字列の末尾のホワイトスペース除去 |
trimLeftInPlace | 文字列の先頭のホワイトスペース除去(元の文字列を更新) |
trimRightInPlace | 文字列の末尾のホワイトスペース除去(元の文字列を更新) |
toLower | 文字列を小文字に変換 |
toLowerInPlace | 文字列を小文字に変換(元の文字列を更新) |
toUpper | 文字列を大文字に変換 |
toUpperInPlace | 文字列を大文字に変換(元の文字列を更新) |
icompare | 文字列比較。同じなら0を返す(大文字小文字を同一視) |
replace | 文字列置換(元の文字列をコピーして置換) |
replaceInPlace | 文字列置換(元の文字列を更新) |
translate | 1文字単位の置換 |
cat | 文字列の連結 |
format | sprintfスタイルの書式整形 |
各関数とも、いくつかの引数のパターンが定義されているので、詳しくはリファレンスを見てください。ここでは、基本のパターンのサンプルコードを紹介しておきます。
#include "poco/string.h" std::string str1 = " The above copyright notice\t"; std::string str2 = " shall be included"; std::cout << Poco::cat( str1, str2 ) << std::endl; // (1) std::cout << Poco::cat( Poco::trimRight( str1 ), str2 ) << std::endl; // (2) std::cout << Poco::cat( Poco::trimInPlace( str1 ), str2 ) << std::endl; // (3) std::cout << Poco::cat( str1, str2 ) << std::endl; // (4) std::cout << Poco::cat( str1, Poco::toUpper( str2 ) ) << std::endl; // (5) std::cout << Poco::icompare( str2, Poco::toUpper( str2 ) ) << std::endl; // (6) std::cout << Poco::translate( str1, std::string("co"), std::string("12") ) << std::endl; // (7) std::cout << Poco::replace( str1, std::string("co"), std::string("12") ) << std::endl; // (8)
- コメント(1)の行は、単純な文字列連結です。
- (2)は、文字列str1の終端のホワイトスペースが除かれています。
- (3)は、文字列str1の両端のホワイトスペースを除去し、文字列str1自体を更新しています。
- (4)は、(1)と同じコードですが、str1が更新されているので、(3)と同じ結果となります。
- (5)は、str2を大文字に変換しています。
- (6)は、大文字小文字を区別しないので、等しいということで0を出力します。
- (7)は、「c」を「1」、「o」を「2」に変換しています。
- (8)は、「co」を、単純に「12」と置換しています。
実行結果は、次のようになります。
The above copyright notice shall be included The above copyright notice shall be included The above copyright notice shall be included The above copyright notice shall be included The above copyright notice SHALL BE INCLUDED 0 The ab2ve 12pyright n2ti1e The above 12pyright notice
以上の関数は、特にUTF-8コードを考慮しているわけではありません。いくつかはUTF-8コードに対応したバージョンが別に用意されており、「Poco/UTF8String.h」に定義されています。
- icompare()
- toUpper()
- toUpperInPlace()
- toLower()
- toLowerInPlace()
使い方は、次のようになります。
#include "Poco/UTF8String.h" s = Poco::UTF8::toUpper( str2 );
format
std::stringを利用していて、いちばん不便なのは、printfのような書式整形するメソッドがないことです。POCOでは、printf相当の機能を実装したタイプセーフなformat関数が提供されています。
基本の定義は、
std::string format( const std::string & fmt, const Any & value );
となっていて、fmt
で書式を指定し、value
で出力する値を指定します。引数は制限のないprintfと異なり1~6個までとなっており、書式で指定した型と異なる場合はBadCastException例外が送出されます。
Anyは、POCOで定義されているすべての型を表すクラスです。
書式指定は次の形式となります。
%[<flags>][<width>][.<precision>][<modifier>]<type>
指定できる書式は、基本的にはprintfのサブセットとなっています。詳しくはリファレンスで確認してください。
#include "poco/format.h" s = Poco::format( "%s + %d = %x", std::string("10"), 2, (unsigned int)12 ); // 10 + 2 = c
型のチェックは厳密になっています。例えば、サンプルコードのような16進数や、8進数表示では、unsignedの数値型が求められます。
BOOSTでは
ちなみに、POCOと同じC++のオープンソースライブラリとして有名なBOOSTにも、boost::formatというクラスがあります。こちらはPOCOとは異なり、かなり斬新な書き方となっています。
// %1%が1番目のパラメータ、%2%が2番目のパラメータに置き換わります。 s = boost::format("%1% %2%") % "test" % 123; // printfスタイル // %03d:0詰めで3桁の整数 %f:浮動小数点 %x:16進数表記 s = boost::format("%03d %f %x") % 123 % 1.23 % 12;
StringTokenizer
関数だけでなく、ちょっとした機能を実装したクラスもあります。StringTokenizerは、そんなクラスの1つです。
JavaのパッケージにあるStringTokenizerクラスと同様のクラスで、任意の文字列を指定されたデリミタで分割するクラスです。コンストラクタで対象となる文字列と区切り文字のデリミタを指定します。分割されたトークンの参照は、イテレータを利用するか、配列のように[]
での添え字指定となります。
次のサンプルコードは、文字列をUTF-8に変換し、カンマ区切りでトークンに分割しています。そして、前述のcatを使い、セミコロンを区切り文字にしてトークンを連結しています。このようにcatは、イテレータで指定したものを連結することもできます。
#include "poco/Stringtokenizer.h" std::string str1 = "ある日,事,御釈迦様,極楽," "の蓮池,ふち,独り,ぶらぶら,歩き,"; // UTF-8に変換した文字列を","で分割 Poco::StringTokenizer words( ShitJIStoUTF8( str1 ), "," ); // 分割されたトークンをすべて表示 Poco::StringTokenizer::Iterator it; for ( it = words.begin(); it != words.end(); it++ ) std::cout << UTF8toShitJIS(*it) << std::endl; // デリミタをつけて連結 std::string str2 = Poco::cat( std::string(";"), words.begin(), words.end() ); // シフトJISに変換して表示 std::cout << UTF8toShitJIS(str2) << std::endl;
実行結果は次のようになります。
ある日 事 御釈迦様 極楽の蓮池 ふち 独り ぶらぶら 歩き ある日;事;御釈迦様;極楽の蓮池;ふち;独り;ぶらぶら;歩き
ストリーム処理
std::stringのようなオンメモリでの処理だけでなく、POCOでは、テキストをストリームとして処理する上で、便利なクラスも提供されています。特にファイルストリームと組みあわせると効果的ですので、ストリームに関してはファイル処理をとりあげるときに併せて紹介したいと思います。
まとめ
今回は、プログラムの基礎的な部分でもあるテキスト処理をとりあげました。最後のStringTokenizerクラスはどこまで実用性があるかどうか分かりませんが、タイプセーフなformat関数はなかなか便利に使えるのではないでしょうか。
C++言語での実装にお役に立てれば幸いです。
参考資料
- POCO C++ Libraries Reference
- 「できるプログラマになるためのAPIで学ぶWindows徹底理解」(安室 浩和 著・日経ソフトウエア 編、日経BP社、2004年4月)
- MSDN Library Japan