ナビゲーションリンクをスキップ | |
印刷ビューの終了 | |
Oracle Solaris Studio 12.3: C++ ユーザーズガイド Oracle Solaris Studio 12.3 Information Library (日本語) |
定義済みの iostream 以外のストリームを読み込む、あるいは書き込む場合は、ユーザーが自分で iostream を生成する必要があります。これは一般には、iostream ライブラリで定義されている型のオブジェクトを生成することになります。ここでは、使用できるさまざまな型について説明します。
ファイル操作は標準入出力の操作に似ています。ifstream、ofstrea m、fstream の 3 つのクラスはそれぞれ、istream、ostream、iostream の各クラスから派生しています。この 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 を出力ストリームに挿入するのが一般的です。「13.10 streambuf ストリームの操作」と、sbufpub(3CC4) のマニュアルページを参照してください。
このモードは、列挙型 open_mode の各ビットの or で構築されます。これは、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);
ファイルを指定せずに fstream の宣言だけを行い、のちにファイルをオープンすることもできます。次の例では出力用の ofstream toFile を作成します。
ofstream toFile; toFile.open(argv[1], ios::out);
fstream をいったんクローズし、また別のファイルでオープンすることができます。たとえば、コマンド行で与えられるファイルリストを処理するには次のようにします。
ifstream infile; for (char** f = &argv[1]; *f; ++f) { infile.open(*f, ios::in); ...; infile.close(); }
標準出力の整数 1 などのようにファイル記述子がわかっている場合は、次のようにファイルをオープンできます。
ofstream outfile; outfile.attach(1);
fstream コンストラクタの 1 つにファイル名を指定してファイルをオープンしたり、open 関数を使用してオープンしたファイルは、fstream が delete によって破壊されるか、スコープ外に出る時点で自動的にクローズされます。attach で fstream に結合したファイルは、自動的にはクローズされません。
ファイル内の読み込み位置と書き込み位置を変更することができます。そのためには次のようなツールがあります。
tellg (tellp) は istream (ostream) のメンバー関数で、現在のファイル内の位置を返します。istream と ostream は fstream の親クラスであるため、tellg と tellp も fstream クラスのメンバー関数として呼び出すことができます。
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 の値にいつでも戻ることができます。