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