Up

簡単なファイル入出力C++プログラミング

 

 ファイルへの入出力は、コンソールでの入出力と同じ要領で行うことができる。コンソールでの入出力は、coutcinを用いるが、ファイルへの入出力は、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;

}

 

 cincout を用いるときはヘッダーファイルiostream#includeするが、ifstream型および ofstream型を用いるときはヘッダーファイルfstream#includeする。

ファイル入出力用オブジェクトを

ifstream fin;

ofstream fout; 

と用意したとき、入力ファイル名と出力ファイル名がchar型の配列nm nm1 に設定されているなら、

fin.open(nm);

fout.open(nm1);

open関数によってfinあるいはfoutnm あるいは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>             //      cincout の使用のため

#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++プログラミング入門」勁草書房>を上梓した。

 

Up