2-1. ファイルとストリーム

公開日: 16:04 2. 応用編/2-1. ファイルとストリーム

これまでiostream標準ライブラリを使い、cincoutが提供する方法で標準入力からの読み取りと標準出力への書き込みをそれぞれ行ってきました。 このチュートリアルではどのようにしてファイルからの読み取りと書き込みを行うかを学びます。これにはfstreamというC++標準ライブラリが必要になり、3つの新しい型を定義しています。

データ型説明
ofstreamこのデータ型は出力ファイルストリームを表し、ファイルの 作成やファイルに書き込みを行うのに使用されます。
ifstreamこのデータ型は入力ファイルストリームを表し、ファイル の読み込みに使われます。
fstreamこのデータ型は一般的にファイルストリームを表し、 ofstreamとifstreamの両方と互換性を持ちます。これはファイルの作成、ファイルへの 書き込み、ファイルからの読み込みが可能であることを意味します。

C++でファイル処理を実行するためには、<iostream >と<fstream>ヘッダファイルがC++ソースコードでインクルードされていなければなりません。

ファイルのオープン

ファイルの読み込みや書き込みをする前にファイルを開く必要があります。ofstreamとfstreamオブジェクトはいずれも書き込むためにファイルを開くのに使われ、ifstreamオブジェクトは読み込み専用でファイルを開くのに使われます。 

以下はopen()関数の標準的な構文であり、open()関数はfstream、ifstream、ofstreamオブジェクトのメンバです。
void open( const char *filename, ios::openmode mode );
最初の引数は開くファイルの場所と名前を指定し、2つめの引数は開くファイルのモードを定義します。

モードフラグ説明
ios::appアペンドモード。ファイルへのすべての出力は最後に追加されます。
ios::ate出力用にファイルを開き、読み込み・書き込み制御をファイルの最後に移動します。
ios::in読み込み用にファイルを開きます。
ios::out書き込み用にファイルを開きます。
ios::truncファイルが既にある場合、その内容がファイルを開く前に切り捨てられます。

これらの値をORを使って2つ以上組み合わせることができます。書き込み用にファイルを開き、且つすでにファイルが有るのであれば切り捨てたい時は次のような構文になります。
ofstream outfile;
outfile.open( "file.dat", ios::out | ios:: trunc );

同様に、次のようにしてファイルを読み込みと書き込み目的で開くことができます。
fstream afile;
afile.open( "file.dat", ios::out | ios::in );

ファイルを閉じる

C++プログラムが終了するときプログラムは自動的にすべてのストリームを閉じ、メモリを開放し、開いたファイルを閉じます。しかし、プログラムが終わる前に開いたファイルを閉じるようにするとプログラマにとって良い習慣となります。 次の例はclose()関数の標準的な構文です。close()関数はfstream、ifstream、ofstreamオブジェクトのメンバです。
void close();

ファイルへの書き込み

C++では、画面に情報を出力した時のように、挿入演算子(<<)を使ってプログラムから情報をファイルに書き込みます。違いはcoutオブジェクトの代わりにifstreamまたはfstreamオブジェクトを使うことだけです。

ファイルからの読み込み

キーボードから情報を入力した時のように、抽出演算子(>>)を使ってファイルからからプログラムに情報を読み込みます。違いはcinオブジェクトの代わりにofstreamまたはfstreamオブジェクトを使うことだけです。

読み込みと書き込みのサンプル

次のC++プログラムはファイルを読み込みと書き込みモードで開きます。ユーザに入力された情報をafile.datという名前でファイルに書き込んだ後、ファイルから情報を読み込み画面に出力します。

#include <fstream>
#include <iostream>
using namespace std;
 
int main ()
{
    
   char data[100];

   // ファイルを書き込みモードで開く
   ofstream outfile;
   outfile.open("afile.dat");

   cout << "ファイルに書き込み中" << endl;
   cout << "名前を入力してください: "; 
   cin.getline(data, 100);

   // 入力されたデータをファイルに書き込み
   outfile << data << endl;

   cout << "年齢を入力してください: "; 
   cin >> data;
   cin.ignore();
   
   // 再度入力されたデータをファイルに書き込む
   outfile << data << endl;

   // 開いたファイルを閉じる
   outfile.close();

   // ファイルを読み込みモードで開く
   ifstream infile; 
   infile.open("afile.dat"); 
 
   cout << "ファイルを読込中" << endl; 
   infile >> data; 

   // 画面にデータを出力
   cout << data << endl;
   
   // 再度データを読み込み画面に表示
   infile >> data; 
   cout << data << endl; 

   // 開いたファイルを閉じる
   infile.close();

   return 0;
}
上のコードをコンパイルし実行すると、次のようになります。
ファイルに書き込み中
名前を入力してください: Zara
年齢を入力してください: 9
ファイルを読込中
Zara
9

上の例ではcinオブジェクトの追加関数を使っており、getline()関数は外部ファイルを1行読み取り、ignore()関数は前回読み込んだ残りの文字を無視します。

ファイル位置ポインタ

istreamostreamはどちらもファイル位置ポインタを再配置するメンバ関数を備えています。これらのメンバ関数はistreamはseekg(seek get)、ostreamはseekp(seek put)です。
seekgとseekpへの引数は一般的にlong intです。2つ目の引数でシーク方向を指定できます。シーク方向をストリームの先頭に配置するにはios::beg(デフォルト)、ストリームの現在位置に配置するにはios::cur、ストリームの終わりに配置するにはios::endを使います。

ファイル位置ポインタはファイルの開始場所のバイト数と同様に、ファイル場所を指定する整数値です。ファイル位置ポインタ取得の位置決めの例は次のようになります。
// fileObjectの(ios::begから)nバイト目へ移動
fileObject.seekg( n );

// fileObjectのnバイト先へ移動
fileObject.seekg( n, ios::cur );
// fileObjectの終わりからnバイト目へ移動
fileObject.seekg( n, ios::end );

// fileObjectの終わりへ移動
fileObject.seekg( 0, ios::end );
  • ?±??G???g???[?d????u?b?N?}?[?N???A

0 件のコメント :

コメントを投稿