Oracle® Solaris Studio 12.4: C++ ユーザーズガイド

印刷ビューの終了

更新: 2014 年 12 月
 
 

13.4.1 クラス fstream を使用したファイル操作

ファイル操作は標準入出力の操作に似ています。ifstreamofstreamfstream の 3 つのクラスはそれぞれ、istreamostreamiostream の各クラスから派生しています。この 3 つのクラスは派生クラスなので、挿入演算と抽出演算、および、そのほかのメンバー関数を継承しており、ファイル使用のためのメンバーとコンストラクタも持っています。

fstream のいずれかを使用するときは、fstream.h をインクルードします。入力だけ行うときは ifstream、出力だけ行うときは ofstream、入出力を行うときは fstream を使用します。コンストラクタへの引数としてはファイル名を渡します。

thisFile というファイルから thatFile というファイルへのファイルコピーを行うときは、次のコーディング例のようになります。

ifstream fromFile("thisFile");
if     (!fromFile)
    error("unable to open ’thisFile’ for input");
ofstream toFile ("thatFile");
if     (!toFile)
    error("unable to open ’thatFile’ for output");
char c;
while (toFile && fromFile.get(c)) toFile.put(c);

このコードは次を実行します。

  • fromFile という ifstream オブジェクトをデフォルトモード ios::in で生成し、それを thisFile に結合します。thisFile をオープンします。

  • 新しい ifstream オブジェクトのエラー状態を調べ、エラーであれば関数 error を呼び出します。関数 error は、プログラムの別の場所で定義されている必要があります。

  • toFile という ofstream オブジェクトをデフォルトモード ios::out で生成し、それを thatFile に結合します。

  • 上記のように、toFile のエラー状態を検査します。

  • データの受け渡しに使用する char 型変数を生成します。

  • fromFile の内容を一度に 1 文字ずつ toFile にコピーします。


    注 - ファイルをこのように、一度に 1 文字ずつコピーすることは望ましくありません。このコードは fstream の使用例として示したにすぎません。実際には、入力ストリームに関係付けられた streambuf を出力ストリームに挿入するのが一般的です。streambuf ストリームの操作と、sbufpub(3CC4) のマニュアルページを参照してください。

13.4.1.1 オープンモード

このモードは、列挙型 open_mode の各ビットの論理和で構築されます。これは、ios クラスの公開部であり、次の定義を持ちます。

enum open_mode {binary=0, in=1, out=2, ate=4, app=8, trunc=0x10,
     nocreate=0x20, noreplace=0x40};

注 - UNIX では binary フラグは必要ありませんが、これを必要とするシステムとの互換性を保つために提供されています。移植可能なコードにするためには、バイナリファイルをオープンするときに binary フラグを使用する必要があります。

入出力両用のファイルをオープンできます。たとえば次のコードでは、someName という入出力ファイルをオープンして、fstream 変数 inoutFile に結合します。

fstream inoutFile("someName", ios::in|ios::out);

13.4.1.2 ファイルを指定しない fstream の宣言

ファイルを指定せずに fstream の宣言だけを行い、のちにファイルをオープンすることもできます。次の例では出力用の ofstream toFile を作成します。

ofstream toFile;
toFile.open(argv[1], ios::out);

13.4.1.3 ファイルのオープンとクローズ

fstream をいったんクローズし、また別のファイルでオープンすることができます。たとえば、コマンド行で与えられるファイルリストを処理するには次のようにします。

ifstream infile;
for (char** f = &argv[1]; *f; ++f) {
   infile.open(*f, ios::in);
   ...;
   infile.close();
}

13.4.1.4 ファイル記述子を使用したファイルのオープン

標準出力の整数 1 などのようにファイル記述子がわかっている場合は、次のようにファイルをオープンできます。

ofstream outfile;
outfile.attach(1);

fstream コンストラクタの 1 つにファイル名を指定してファイルをオープンしたり、open 関数を使用してオープンしたファイルは、fstreamdelete によって破壊されるか、スコープ外に出る時点で自動的にクローズされます。attachfstream に結合したファイルは、自動的にはクローズされません。

13.4.1.5 ファイル内の位置の再設定

ファイル内の読み込み位置と書き込み位置を変更することができます。そのためには次のようなツールがあります。

  • streampos は、iostream 内の位置を記憶しておくためのデータ型です。

  • tellg (tellp)istream (ostream) のメンバー関数で、現在のファイル内の位置を返します。istreamostreamfstream の親クラスであるため、tellgtellpfstream クラスのメンバー関数として呼び出すことができます。

  • seekg (seekp)istream (ostream) のメンバー関数で、指定したファイル内の位置を探し出します。

  • enum seek_dir は、seek での相対位置を指定します。

    enum seek_dir {beg=0, cur=1, end=2};

    fstream aFile の位置再設定の例を次に示します。

    streampos original = aFile.tellp();     //save current position
    aFile.seekp(0, ios::end); //reposition to end of file
    aFile << x;               //write a value to file
    aFile.seekp(original);    //return to original position

    seekg (seekp) は、1 つまたは 2 つの引数を受け取ります。引数を 2 つ受け取るときは、第 1 引数は、第 2 引数で指定した seek_dir 値が示す位置からの相対位置となります。例:

    aFile.seekp(-10, ios::end);

    この例では、ファイルの最後から 10 バイトの位置に設定されます。

    aFile.seekp(10, ios::cur);

    一方、次の例では現在位置から 10 バイト進められます。


    注 - テキストストリーム上での任意位置へのシーク動作はマシン依存になります。ただし、以前に保存した streampos の値にいつでも戻ることができます。