簡単なファイル入出力C++プログラミング
ファイルへの入出力は、コンソールでの入出力と同じ要領で行うことができる。コンソールでの入出力は、cout、cinを用いるが、ファイルへの入出力は、ifstream 型および ofstream 型のストリームと呼ばれるオブジェクトを用いる。例えば、
ifstream fin; // ファイル読み込み用ストリームオブジェクト fin の定義
ofstream fout; // ファイル書き出し用ストリームオブジェクト fout の定義
と定義すると、fin および fout
によってファイルへの入出力が cin および cout を用いるときと同じように行うことができる。このことを次のサンプルプログラムによって説明する。
#include "stdafx.h" // Visual C++用。Linuxのときは不要。
#include <iostream> // cin, cout を使用するため
#include <fstream> // ifstream, ofstream を使用するため
using namespace std;
int _tmain(int argc,
_TCHAR* argv[]){ // Linux
のときは、 int main(){ とする
ifstream fin; // ファイル読み込み用ストリームオブジェクト fin の定義
ofstream fout; // ファイル書き出し用ストリームオブジェクト fout の定義
cout << "Data file name = ";
char
nm[100];
cin >>
nm; // ファイル名を nm に設定
fin.open(nm); // nm に設定された名前のファイルを fin に割り当てる
if (fin.fail()){ // fin.open(nm)の失敗:nmで指定したファイルが存在しない?
cout << "Opening the
input file failed." << endl;
cout << "Press
Enter-key." << endl;
cin.get(); // Linuxのときは不要
cin.get(); // Linuxのときは不要
return 9;
}
cout << "Output
file name = ";
char
nm1[100];
cin >>
nm1; // 出力用ファイル名の設定
fout.open(nm1); // nm1
に設定された名前のファイルを fout に割り当てる
fout << "Data file = " << nm << endl << endl;
int n = 0;
double
data[100];
while(true){
fin >> data[n]; // fin から data[n] に読み込む
if (fin.fail()) break; // 直前の「fin >> data[n];」の失敗:読み込むデータが存在しなかった?
n++;
}
fin.close(); // fin を閉じる
for (int i
= 0; i < n; i++)
fout << "data[" << i+1 << "] = " << data[i]
<< endl; // fout への書き出し
fout.close();
cout << endl
<< n << " 個のデータが処理されました。"
<< endl;
cout << endl << "Enterキーを押して下さい。" << endl;
cin.get(); // Linuxのときは不要
cin.get(); // Linuxのときは不要
return 0;
}
cin、cout を用いるときはヘッダーファイルiostreamを#includeするが、ifstream型および ofstream型を用いるときはヘッダーファイルfstreamを#includeする。
ファイル入出力用オブジェクトを
ifstream fin;
ofstream fout;
と用意したとき、入力ファイル名と出力ファイル名がchar型の配列nm と nm1 に設定されているなら、
fin.open(nm);
fout.open(nm1);
とopen関数によってfinあるいはfoutをnm あるいはnm1 に設定されている名前のファイルに割り当てることができる。nmに設定された名前のファイルが存在しないときは、関数
fin.fail()
はtrueを返す。
ファイルへの入出力は、cin あるいは cout と同じく、演算子 << あるいは >> によって行う。例えば、
fin >> data[n];
によって、fin に割り当てられているファイルからdata[n] にデータが読み込まれる。ファイルからデータがすべて読み込まれ、もう data[n] に読み込むデータが存在しないときは、この「fin >> data[n];」の実行後の関数 fin.fail() の値はfalse になる。
上のプログラムにおいて
cin.get();
は、Enterキーが押されるまで待つものである。これにより、プログラムの終了がEnterキーが押されるまで待たされることになる。cin.get()が2回続いているのは、その前にcinによる入力「cin >> nm;」があることによる。cin.get()の実行前にcinの呼び出しがなく、用いられているのがcoutのみの場合は、cin.get()の実行は1回でよい。この場合、cin.get() が2回書かれたときは、Enterキーを2回押せばよい。
上のプログラムを実行したときの画面の例が図1である。
図1
読み込み用データファイル「data.txt」は図2に示すように用意されている。
図2
データファイルがプログラムのソースコードファイルと同じフォルダに置かれているときは、ファイル名の指定だけでよい。出力ファイルも図1のように指定すると、プログラムのソースコードファイルと同じフォルダに作成される。
図2の入力データのときの出力ファイルは図3のようになる。
図3
ifstream 型のオブジェクト fin からの読み込みは、空白文字、タブ、あるいは改行はデータの区切りとして同じ扱いなので、図2のデータは図4のように配置しても同じように読み込まれる。
図4
図4のファイルを入力データファイルとして実行したときのコンソール画面を図5に示す。
図5
このときの出力ファイルの内容を図6に示す。図3のものと同じである。
図6
データの最初の部分にコメントがある場合は、特定の文字まで読み飛ばすことになる。図7のデータファイルの場合は、スラッシュ / まで読み飛ばし、その後からデータを読み込めばよい。
図7
スラッシュ / まで読み飛ばすプログラム例を以下に示す。
#include "stdafx.h" // Visual C++ 用。Linux では不要。
#include <iostream> // cin, cout
#include <fstream> // ifstream, ofstream
using namespace std;
int _tmain(int argc,
_TCHAR* argv[]){ // Linux のときは、 int main(){ とする
ifstream fin; // ファイル読み込み用ストリームオブジェクト fin の定義
ofstream fout; // ファイル書き出し用ストリームオブジェクト fout の定義
cout << "Data file
name = ";
char nm[100];
cin >> nm;
fin.open(nm);
if (fin.fail()){ // fin.open(nm)の失敗:nmで指定したファイルが存在しない?
cout << "Opening the
input file failed." << endl;
cout << "Press
Enter-key." << endl;
cin.get();
cin.get();
return 9;
}
cout << "Output
file name = ";
char nm1[100];
cin >> nm1;
fout.open(nm1);
fout << "Data file =
" << nm << endl << endl;
while(true){
char c;
fin
>>c;
if (c == '/') break; // スラッシュ / まで読み飛ばし
}
int n = 0;
double data[100];
while(true){
fin
>> data[n];
if (fin.fail()) break; // 直前のfin >> data[n]の失敗:読み込むデータが存在しなかった?
n++;
}
fin.close();
for (int
i = 0; i < n; i++)
fout << "data["
<< i+1 << "] = "
<< data[i] << endl;
fout.close();
cout << endl
<< n << " 個のデータが処理されました。"
<< endl;
cout << endl << "Enterキーを押して下さい。" << endl;
cin.get();
cin.get();
return 0;
}
上のプログラムでは、 while 文
while(true){
char c;
fin
>>c;
if (c == '/') break; // スラッシュ / まで読み飛ばし
}
によって、スラッシュ / まで読み飛ばしている。
書式制御
書き出しの形式は、setw などのマニピュレータと呼ばれているものによって行うことができる。プログラム例を以下に示す。
#include "stdafx.h" // Visual
C++ 用に必要、Linux の場合は不要
#include <iostream> // cin、cout の使用のため
#include <fstream> // ofstream の使用のため
#include <iomanip> // manipulator使用のため
#include <cmath> // 数学関数 sqrt 使用のため
using namespace std;
int _tmain(int argc,
_TCHAR* argv[]) // Linux
のときは、 int main() とする
{
char nm[100];
cout << "Output File
Name = ";
cin >> nm;
ofstream fout; // 出力用ファイルのストリーム
fout.open(nm); // nm
に設定された名前のファイルを fout に割り当てる
double a = 1.0/3.0, b = 1.0 / 6.0, c = sqrt(2.0);
fout << a << "
" << b << " "
<< c << endl;
// setw で出力幅を設定。直後の出力のみに有効
fout << setw(20);
fout << a << "
" << b << " "
<< c << " " <<
100.0*c << endl;
fout << setw(20) << a
<< setw(20) << b << setw(20) << c << setw(20)
<< 100.0*c << endl;
// マニピュレータ left の使用
fout << left << setw(20)
<< a << setw(20) << b << setw(20) << c << setw(20)
<< 100.0*c << endl;
// マニピュレータ right により、途中から右寄せで出力
fout << left << setw(20)
<< a << setw(20) << b << setw(20) << right << c << setw(20) << right << 100.0*c << endl;
// マニピュレータ setprecision により出力桁数を指定
fout << setprecision(10);
fout << left << setw(20)
<< a << setw(20) << b << setw(20) << right << c << setw(20) << right << 100.0*c << endl;
fout << fixed;
fout << left << setw(20)
<< a << setw(20) << b << setw(20) << right << c << setw(20) << right << 100.0*c << endl;
// マニピュレータ scientific により、指数表現で出力
fout << scientific;
fout << left << setw(20)
<< a << setw(20) << b << setw(20) << right << c << setw(20) << right << 100.0*c << endl;
// マニピュレータ fixed により、少数表現で出力
fout << fixed;
fout << left << setw(20)
<< a << setw(20) << b << setw(20) << right << c << setw(20) << right << 100.0*c << endl;
// 関数 unsetf(ofstream::floatfield) の呼び出しにより、浮動小数点数の出力をデフォルト状態に戻す。
fout.unsetf(ofstream::floatfield);
fout << left << setw(20)
<< a << setw(20) << b << setw(20) << right << c << setw(20) << right << 100.0*c << endl;
fout << setprecision(6);
fout << left << setw(20)
<< a << setw(20) << b << setw(20) << right << c << setw(20) << right << 100.0*c << endl;
fout.close();
return 0;
}
上のプログラムの実行時の画面は、図8のようになる。
図8
出力ファイル名を設定して、Enterキーを押すと、プログラムはすぐに実行終了となり、図8のコンソール画面は閉じられる。実行終了後、出力ファイルとして指定したファイルを開くと、図9のようになっている。
図9
図9の出力と上のプログラムを対応させることによって、マニピュレータ
setw(n) 出力をn文字の文字幅で行う。直後の出力に対して有効
left setw(n)で設定された文字幅内で左詰めで出力
right setw(n)で設定された文字幅内で右詰で出力
setprecision(n) n 桁の精度で出力
fixed 小数表現で出力
scientific 指数表現で出力
の効果を確認することができる。また、ストリームの関数
fout.unsetf(ofstream::floatfield);
によって、浮動小数点数の出力をデフォルトに戻すことができる。
なお、Visual C++プログラミングの入門解説書として<岡本安晴「大学生のための心理学VC++プログラミング入門」勁草書房>を上梓した。