Rogue Wave バナー
前へマニュアルの先頭へ目次次へ

11.4 抽出子と挿入子の応用

日付の書式は、地域や文化の規約によって異なります。したがって、抽出子と挿入子についての日付の構文解析や書式設定は、通常、そのような規約に基づいて行います。抽出子と挿入子にそれらの機能を追加するには、次の例のように、個々のストリームのロケールに組み込んだ時間ファセットを使用します。

template<class charT, class Traits>
basic_istream<charT, Traits>&
operator >> (basic_istream<charT, Traits >& is, date& dat)
{
 ios_base::iostate err = 0;
 
 use_facet<time_get<charT,Traits> >(is.getloc())              //1
   .get_date(is, istreambuf_iterator<charT,Traits>()          //2
            ,is, err, &dat.tm_date);                          //3

 return is;
}
//1 入力ストリームのロケールの time_get ファセットによって、ロケールで定義した文化的規約に基づいて日付の構文解析を処理します。問題のロケールは、ストリームの getloc() 関数で呼び出します。time_get ファセットは、use_facet<..>() 大域関数に対する呼び出しでアクセスします。use_facet 関数テンプレートの型引数は、ファセット型です (ロケールとファセットの詳細については、国際化の章を参照してください)。
//2 ファセットのメンバー関数 get_date() を呼び出します。この関数は、次のように多くの引数をとります。

入力反復子の範囲。パフォーマンスと効率性の理由から、ファセットはストリームのバッファで直接操作します。ファセットは、ストリームのバッファ反復子でストリームバッファにアクセスします (『標準 C++ ライブラリ・ユーザーズガイド』のストリームバッファ反復子の節を参照)。標準 C++ ライブラリのストリームバッファ反復子の規約にもとづいて、反復子の範囲を設定します。範囲はアクセスする最初の文字を示す反復子から、アクセスする最後の文字の後の文字までです (終了位置の後)。

入力シーケンスでは、まずストリームを参照します。istreambuf_iterator クラスにはコンストラクタがあり、ここで入力ストリームを参照します。そのため、ストリームに対する参照は、ストリーム内の現在の位置を示す istreambuf_iterator に自動的に変換されます。入力シーケンスの最後に、ストリームの最後の反復子が読み込まれます。これは、クラス istreambuf_iterator のデフォルトのコンストラクタによって作成されます。以上 2 つのストリームバッファ反復子では、入力ストリームの現在の位置から、日付や無効な文字が見つかるか、入力ストリームの最後に達するまで、入力の構文解析が行われます。
//3 他のパラメータは、次のとおりです。

書式設定フラグ。ストリームの ios_base 部までの参照をここで指定します。これは、ストリームのメンバー flags()precision()width() に対して、ファセットでストリームの書式設定情報を適用するためです。

入出力ストリームの状態。日付の構文解析時のエラー報告に使用します。

時間オブジェクトに対するポインタ。tm 型のオブジェクトに対するポインタです。C ライブラリで定義した時間構造です。日付クラスでは、このような時間構造によって個々のデータメンバー tm_date にポインタを渡します。

挿入子も同様に構築します。

template<class charT, class Traits>
basic_ostream<charT, Traits>& operator << 
 (basic_ostream<charT, Traits >& os, const date& dat)
{
   use_facet 
   <time_put<charT,ostreambuf_iterator<charT,Traits> > >      //1
   (os.getloc())
   .put(os,os,os.fill(),&dat.tm_date,'x');                    //2
   return os;
}
//1 ストリームのロケールの time_put ファセットを使用して、日付の書式設定を処理します。
//2 ファセットの put() 関数の引数は、次のとおりです。

出力反復子ostreambuf_iterator に対する出力ストリームへの参照から、自動変換を使用します。出力は、現在の書き込み位置から出力ストリームに挿入されます。

書式設定フラグ。ストリームの ios_base 部に参照を与えます。これは、ストリームの書式設定情報を検索するときにファセットで使用します。

空白詰め文字。ストリームの空白詰め文字を使用します。他の空白詰め文字を使用することもできますが、通常はストリームの設定を使用します。

時間構造に対するポインタ。構文解析の結果がこの構造に保存されます。

書式指示子。例にもある 'x' のような文字です。%"%A, %B %d, %Y")。C ライブラリの strftime() 関数の書式指示子と同じはたらきがあります。出力される日付は、Tuesday, June 11, 1996 のようになります。ここでは、書式指示子は使用せず、ロケールの適切な日付表現を指定する簡単な文字として 'x' を使用します。

以上の挿入子と抽出子が、先の簡単な例と比較してどれだけ違うかを確認してください。以後は、operator<<(int)date オブジェクトのデータメンバーを個別に挿入したときのように、組み込み型の既存の挿入子や抽出子だけに頼る必要はありません。代わりに、time ファセットの get_date() サービスのような、低レベルサービスを使用します。書式制御やエラー処理など、これまで使用してきた挿入子や抽出子のような高レベルのサービスの機能は必要ありません。

ストリームのバッファに直接アクセスすることで、プログラムの実行時の効率面でおそらく同じ成果が得られます。ストリームのバッファのサービスも、書式制御やエラー処理などのタスクを自分で運用することができる低レベルサービスです。

以下の節では、ロケールやストリームバッファなどの低レベル構成要素を直接的に使用して、挿入子と抽出子を改良して完成する方法を説明します。


前へマニュアルの先頭へ目次次へ

Copyright (c) 1998, Rogue Wave Software, Inc.
このマニュアルに関する誤りのご指摘やご質問は、電子メールにてお送りください。


OEM リリース, 1998 年 6 月