SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

オープンソースC++用クラスライブラリPOCO活用講座

テキスト処理もPOCOにおまかせ

オープンソースC++用クラスライブラリPOCO活用講座(3)

  • X ポスト
  • このエントリーをはてなブックマークに追加

ユーティリティ関数

 POCOには、Unicode関連以外にも、汎用的に使えるような関数がいくつか定義されています。その中のテキスト処理に関するものを以下にまとめました。

string補助クラス

 POCOでは、std::stringに代わるような独自の文字列クラスは用意されていません。通常は、std::stringを利用することになりますが、std::stringの機能を補うための関数が用意されています。

std::string補助クラス
関数名概要
trim文字列の先頭と末尾のホワイトスペース除去
trimInPlace文字列の先頭と末尾のホワイトスペース除去(元の文字列を更新)
trimLeft文字列の先頭のホワイトスペース除去
trimRight文字列の末尾のホワイトスペース除去
trimLeftInPlace文字列の先頭のホワイトスペース除去(元の文字列を更新)
trimRightInPlace文字列の末尾のホワイトスペース除去(元の文字列を更新)
toLower文字列を小文字に変換
toLowerInPlace文字列を小文字に変換(元の文字列を更新)
toUpper文字列を大文字に変換
toUpperInPlace文字列を大文字に変換(元の文字列を更新)
icompare文字列比較。同じなら0を返す(大文字小文字を同一視)
replace文字列置換(元の文字列をコピーして置換)
replaceInPlace文字列置換(元の文字列を更新)
translate1文字単位の置換
cat文字列の連結
formatsprintfスタイルの書式整形

 各関数とも、いくつかの引数のパターンが定義されているので、詳しくはリファレンスを見てください。ここでは、基本のパターンのサンプルコードを紹介しておきます。

サンプルコード(format関数以外)
#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()

 使い方は、次のようになります。

サンプルコード(UTF-8対応関数)
#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のサブセットとなっています。詳しくはリファレンスで確認してください。

サンプルコード(format関数)
#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とは異なり、かなり斬新な書き方となっています。

BOOSTサンプルコード(format)
// %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は、イテレータで指定したものを連結することもできます。

StringTokenizerサンプルコード
#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++言語での実装にお役に立てれば幸いです。

参考資料

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
オープンソースC++用クラスライブラリPOCO活用講座連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 高江 賢(タカエ ケン)

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/2098 2008/01/29 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング