ファイル入出力

  ファイルを利用するとき,入力の場合はそのストリームを ifstream クラス,出力の場合は ofstream クラス,また,入力と出力を行う場合は fstream クラスであることを宣言しなければなりません.

  宣言したストリームと,対象とするファイルを関連づけるのが次のメンバー関数です.
void open(char *<ファイル名>, int <モード>, int <アクセス>);		
  モードは,ファイルをどのような状態で開くかを宣言するもので,以下の中から選択します(論理和 | で結合し,一つ以上指定可).
ios::app       : 後ろに追加出力
ios::ate       : ファイルが開かれたときファイルの終わりまでシーク
ios::in        : 入力ファイル
ios::nocreate  : ファイルが存在しないと実行不可能
ios::noreplace : ファイルがすでに存在すると実行不可能
ios::out       : 出力ファイル
ios::trunc     : ファイルが存在するとそれを大きさ 0 のファイルにする		
  アクセスは,どのようにファイルにアクセスできるかを決めるもので,以下の中から選択されます.
0 : 通常ファイル
1 : 読み出し専用ファイル
2 : 隠しファイル
4 : システムファイル
8 : アーカイブビットが on のファイル		
  例えば,通常のファイル test.txt を,出力用にオープンするには,
ofstream st;
st.open("test.txt", ios::out, 0);		
と記述すれば良いことになります.なお,オープンに失敗すると,ストリーム変数の値は 0 になります.

  通常のファイルを入力や出力でオープンする場合は,アクセスやモードに対しデフォルト値を所有しているため,ファイル名だけの指定で十分です.また,ifstream 等のクラスの定義にはファイルを自動的に開くコンストラクタが記述されていますので,例えば,上の例は,
ofstream st("test.txt");		
と書くだけで十分です.ただし,入出力を同時に行うような場合は,次のように,モード指定も必要になります.
fstream st("test.txt", ios::in | ios::out);		
  また,以下のようなメンバー関数を使用することによって,ファイルの状態を検出できます.
int eof()        : ストリームの終わりであれば非 0 値,そうでなければ 0 を返します
int fail()       : ストリームの演算に失敗したとき非 0 値,そうでなければ 0 を返します
int bad()        : fail と似ていますが,もっと悪い状態を表します
int good()       : ストリームに問題がないとき非 0 値,そうでなければ 0 を返します
int operator !() : fail と同じ意味の演算子です.例えば,以下のように使用します.
                   if (!std::cout)
                          失敗したときの処理
operator void*() : 最後のストリーム演算に失敗したとき 0 値,そうでなければ非 0 値を返します.
                   例えば,以下のように使用します.
                       if (std::cin>>c)
                           ・・・
                       else
                           失敗したときの処理		
  次のプログラムは,3 次元空間の点の座標をファイル test1.txt から読み込み,その座標を元に Xyz クラスのインスタンス a を生成し,かつ,その結果をファイル test.txt に出力しています.演算子 << のオーバーロードがファイル出力に対しても有効であることに注意して下さい.

/****************************/
/* ファイル入出力           */
/*      coded by Y.Suganuma */
/****************************/
#include <iostream>
#include <fstream>
#include <stdlib.h>
using namespace std;

/*******************/
/* クラスXyzの定義 */
/*******************/
class Xyz
{
	public:
		int x, y, z;
		Xyz(int a, int b, int c)   /* コンストラクタ */
		{
			x = a;
			y = b;
			z = c;
		}
	friend ostream& operator << (ostream &, Xyz);
};

/******************************************/
/* 座標の表示(演算子<<のオーバーロード) */
/******************************************/
ostream & operator << (ostream &stream, Xyz ten)
{
	stream << "   (" << ten.x << ", ";
	stream << ten.y << ", ";
	stream << ten.z << ")\n";
	return stream;
}

/************/
/* main関数 */
/************/
int main()
{
				// ファイルのオープン
	ifstream in("test1.txt");
	if (!in) {
		cout << "***error  入力ファイルを開けません\n";
		exit(1);
	}

	ofstream out("test.txt");
	if (!out) {
		cout << "***error  出力ファイルを開けません\n";
		exit(1);
	}
				// データ入力と出力
	while (!in.eof()) {
		int n1, n2, n3;
		in >> n1 >> n2 >> n3;
		Xyz a(n1, n2, n3);
		out << a;
	}
				// ファイルのクローズ
	in.close();
	out.close();

	return 0;
}
		

  このプログラムを実行すると,ファイル test1.txt の内容が,
10 20 5
5 4 10		
  であった場合,次のような出力がファイル test.txt になされます.
(10, 20, 5)
(5, 4, 10)		
  参考のため,C の範囲で記述した場合を示しておきます.勿論,クラスや演算子のオーバーロードは使用していません.
/****************************/
/* ファイル入出力           */
/*      coded by Y.Suganuma */
/****************************/
#include <stdio.h>

/************/
/* main関数 */
/************/
int main()
{
				// ファイルのオープン
	FILE *in  = fopen("test1.txt", "r");
	FILE *out = fopen("test.txt", "w");
				// データ入力と出力
	int n1, n2, n3;
	while (EOF != fscanf(in, "%d %d %d", &n1, &n2, &n3))
		fprintf(out, "(%d,%d,%d)\n", n1, n2, n3);
				// ファイルのクローズ
	fclose(in);
	fclose(out);

	return 0;
}