Sun Studio 12: C++ ユーザーズガイド

14.7 マニピュレータ

マニピュレータとは、iostream に挿入したり、iostream から抽出したりする値で特別な効果を持つもののことです。

引数付きマニピュレータとは、 1 つ以上の追加の引数を持つマニピュレータのことです。

マニピュレータは通常の識別子であるため、マニピュレータの定義を多く行うと可能な名前を使いきってしまうので、iostream では考えられるすべての機能に対して定義されているわけではありません。マニピュレータの多くは、この章の別の箇所でメンバー関数とともに説明しています。

定義済みマニピュレータは 13 個あり、それぞれについては表 14–2 で説明します。この表で使用している文字の意味は次のとおりです。

表 14–2 iostream の定義済みマニピュレータ

 

定義済みマニピュレータ 

内容の説明 


ostr << dec, istr >> dec

基数が 10 の整数変換を指定します。 


ostr << endl

復帰改行文字 ('\n') を挿入して、ostream::flush() を呼び出します。


ostr << ends

NULL ( 0 ) 文字を挿入。strstream 使用時に利用します。


ostr << flush

ostream::flush() を呼び出します。


ostr << hex, istr >> hex

基数が 16 の整数変換を指定します。 


ostr << oct, istr >> oct

基数が 8 の整数変換を指定します。 


istr >> ws

最初に空白以外の文字が見つかるまで (この文字以降は istr に残る)、空白を取り除きます (空白を読み飛ばす)。


ostr << setbase(n),  istr >>
setbase(n)

基数が n (0, 8, 10, 16 のみ) の整数変換を指定します。


ostr << setw(n), istr  >> setw(n)

ios::width(n) を呼び出します。フィールド幅を n に設定します。

10 


ostr << resetiosflags(i), istr>>
resetiosflags(i)

i のビットセットに従って、フラグのビットベクトルをクリアします。

11 


ostr << setiosflags(i), istr >>
setiosflags(i)

i のビットセットに従って、フラグのビットベクトルを設定します。

12 


ostr << setfill(c), istr >>
setfill(c)

埋め込み文字 (フィールドのパディング用文字) を c とします。

13 


ostr << setprecision(n), istr
>>setprecision(n)

浮動小数点型データの精度を n 桁にします。

定義済みマニピュレータを使用するには、プログラムにヘッダーファイル iomanip.h をインクルードする必要があります。

ユーザーが独自のマニピュレータを定義することもできます。マニピュレータには次の 2 つの基本タイプがあります。

14.7.1 引数なしのマニピュレータの使用法

引数なしのマニピュレータは、次の 3 つを実行する関数です。

iostream では、このような関数 (へのポインタ) を使用するシフト演算子がすでに定義されていますので、関数を入出力演算子シーケンスの中に入れることができます。シフト演算子は、値の入出力を行う代わりに、その関数を呼び出します。tabostream に挿入する tab マニピュレータの例を示します。


ostream& tab(ostream& os) {
             return os <<’\t’;
            }
...
cout << x << tab << y;

次のコードは、前述の例と同じ処理をより洗練された方法で行います。


const char tab = ’\t’;
...
cout << x << tab << y;

次に示すのは別の例で、定数を使用してこれと同じことを簡単に実行することはできません。入力ストリームに対して、空白の読み飛ばしのオン、オフを設定すると仮定します。ios::setfios::unsetf を別々に呼び出して、skipws フラグをオンまたはオフに設定することもできますが、次の例のように 2 つのマニピュレータを定義して設定することもできます。


#include <iostream.h>
#include <iomanip.h>
istream& skipon(istream &is) {
       is.setf(ios::skipws, ios::skipws);
       return is;
}
istream& skipoff(istream& is) {
       is.unsetf(ios::skipws);
       return is;
}
...
int main ()
{
      int x,y;
      cin >> skipon >> x >> skipoff >> y;
      return 1;
}

14.7.2 引数付きのマニピュレータの使用法

iomanip.h に入っているマニピュレータの 1 つに setfill があります。setfill は、フィールド幅に詰め合わせる文字を設定するマニピュレータで、次の例に示すように定義されています。


// ファイル setfill.cc
#include<iostream.h>
#include<iomanip.h>

// 非公開のマニピュレータ
static ios& sfill(ios& i, int f) {
         i.fill(f);
         return i;
}
// 公開の適用子
smanip_int setfill(int f) {
       return smanip_int(sfill, f);
}

引数付きマニピュレータは、2 つの部分から構成されます。

ヘッダーファイル iomanip.h には、さまざまなクラスが定義されています。各クラスには、マニピュレータ関数のアドレスと 1 つの引数の値が入っています。iomanip クラスについては、manip(3CC4) のマニュアルページで説明しています。 この前の例では、smanip_int クラスを使用しており、ios で使用できます。ios で使用できるということは、istreamostream でも使用できるということです。この例ではまた、int 型の第 2 引数を使用しています。

適用子は、クラスオブジェクトを作成してそれを返します。この前の例では、smanip_int というクラスオブジェクトが作成され、そこにマニピュレータと、適用子の int 型引数が入っています。ヘッダーファイル iomanip.h では、このクラスに対するシフト演算子が定義されています。入出力演算子シーケンスの中に適用子関数 setfill があると、その適用子関数が呼び出され、クラスが返されます。シフト演算子はそのクラスに対して働き、クラス内に入っている引数値 を使用してマニピュレータ関数が呼び出されます。

次の例では、マニピュレータ print_hex は次のことを行います。

この例は出力専用のため、omanip_long クラスが使用されています。 また、int 型でなく long 型でデータを操作します。


#include <iostream.h>
#include <iomanip.h>
static ostream& xfield(ostream& os, long v) {
        long save = os.setf(ios::hex, ios::basefield);
        os << v;
        os.setf(save, ios::basefield);
        return os;
    }
omanip_long print_hex(long v) {
       return omanip_long(xfield, v);
   }