応用プログラミング
第4回
ファイル操作
標準入出力とファイル(P.50)
• これまでのプログラム
入力: キーボード
出力: ディスプレイ
1024 Input an integer 1024標準入出力とファイル(P.50)
• 今回のプログラム
入力:
ファイル
(の内容)
出力:
ファイル
data.dat
Input a file name
リダイレクション(P.50-51)
• Unix OSの機能のひとつ プログラムの作成はこれまで通り行う プログラムを実行する際に, 「<」や「>」の記号を用いて ファイルの入出力を行う // example.cpp int main(){ int x, sum = 0; while(cin >> x){ sum += x; }cout << sum << endl; return 0; } // num.dat 10 -2 5 92 -15 例)整数をいくつか入力し, 和を算出するプログラム 以下のnum.datファイルに保存され ている内容を入力に使いたい…
リダイレクション(P.50-51)
実行ファイル名<
データファイル名 (入力リダイレクト) // num.dat 10 -2 5 92 -15 // 実行例 % example < num.dat 90 「<」を用いて, cin入力の際に ファイルの内容が入力される.<
プログラム実行の際, 入力をファイルから読み込む方法リダイレクション(P.50-51)
実行ファイル名>
記録先ファイル名 (出力リダイレクト) // sum.txt 90<
// 実行例 % example > sum.txt 10↲ -2↲ 5↲ 92↲ -15↲ (ctrl+d) ↲ プログラム実行の際, 出力をファイルに書き込む方法リダイレクション(P.50-51)
実行ファイル名<
データファイル名>
記録先ファイル名 入出力を共にファイルで行う方法 単純に, 入力リダイレクトと出力リダイレクトの両方を行えばよい // num.dat 10 -2 5 92 -15 // 実行例% example < num.dat > sum.txt
<
// sum.txt 90
cin, cout, cerr(P.50-51)
• cinやcoutは<iostream>ヘッダファイルをインクルードすることに よって初めて使えるようになるオブジェクト オブジェクト名 変数型 基本的役割cin
istream
標準入力
cout
ostream
標準出力
cerr
ostream
標準エラー出力
*cerr : プログラムがエラーを通知するための出力変数 標準出力と同様に, 画面(コンソール)に文字を出力するため の変数なので, coutと同じように使える. プログラムの内容に応じて, coutと使い分けるとよい (例:coutは標準出力, cerrは入力エラーの際の出力に用いる) (注:リダイレクトを用いても, cerrは必ず画面に出力される)パイプ(P.52)
• 以下の二つのプログラムを考える odd.cpp : 連続で入力された数字の奇数番目のみを出力する sum.cpp : 入力された数字の合計を求めて出力する • odd.cppの出力をsum.cppで利用するには? 解決策1:そもそも1つのプログラムにしてしまう 解決策2:Unixの機能であるパイプを利用する // 実行例 % odd | sum Input : 12 23 34 45 56 67 (ctrl+d) ↲ Sum : 102 「 | 」の左の出力を右の入力に使用 odd.cppへの入力 sum.cppの出力パイプ(P.52)
• リダイレクションとパイプの組合せも可能// 実行例
% odd < data.dat | sum > sum.txt
// data.dat 12 23 34 45 56 67
<
// sum.txt 102<
指定ファイルからの入力/指定ファイルへの出力(P.53-54)
• リダイレクションもプログラム内で行いたい… <fstream>ヘッダファイルに用意されているファイル入力・出力 に用いるifstream型, ofstream型の変数を用いる. • ifstream型, ofstream型の変数宣言 ifstream 変数名(“ファイル名”) // ファイルの読込 ofstream 変数名(“ファイル名”) // ファイルへの出力 fstream 変数名(“ファイル名”) // ファイルの入出力指定ファイルからの入力/指定ファイルへの出力(P.53-54)
ifstream 変数名(“ファイル名”) // ファイルの読込変数宣言
// ファイル読込の準備部分 ifstream fin(“data.dat”);
if(!fin){
cerr << “cannot open” << endl; return 1; } プログラム冒頭に#include<fstream>と記入することを忘れないこと! finを使うと, data.datからの 読込を行うように宣言 finが正常に宣言されたか (=data.datがちゃんと存在し ているか)どうかをチェック *この後, cinと同様にfinを使うだけで入力リダイレクトと同じになる
指定ファイルからの入力/指定ファイルへの出力(P.53-54)
ofstream 変数名(“ファイル名”) // ファイルへの出力変数宣言
// ファイル出力の準備部分 ofstream fout(“result.txt”);
if(!fout){
cerr << “cannot open” << endl; return 1; } プログラム冒頭に#include<fstream>と記入することを忘れないこと! foutを使うと, result.txtへの 出力を行うように宣言 foutが正常に宣言されたか (=result.txtがちゃんと存在 しているか)どうかをチェック *この後, coutと同様にfoutを使うだけで出力リダイレクトと同じになる
指定ファイルからの入力/指定ファイルへの出力(P.53-54)
// 奇数番目のみ出力するプログラム #include<iostream> #include<fstream> // 忘れないこと! using namespace std; int main(){ int x, num = 1; (1) (2) while(fin >> x){if(num % 2 == 1) fout << x << endl; num++; } return 0; } // ファイル読込の準備部分 ifstream fin(“data.dat”); if(!fin){
cerr << “cannot open” << endl; return 1;
}
// ファイル出力の準備部分
ofstream fout(“result.txt”);
if(!fout){
cerr << “cannot open” << endl; return 1;
ファイル入出力と標準入出力(P.55)
ファイル入出力(fin, fout)と標準入出力(cin, cout)は 組み合わせて使うことができる. 【プログラム例】 ファイルから読み込んだ名簿の中から, キーボードから打ち込んだ名前を探す. キーボードから入力したいくつかの数値を 足し合わせてtxtファイルに記録する. etc…
ファイル入出力と標準入出力(P.55)
#include<iostream> #include<fstream> using namespace std; int main(){ int x, y;bool flag = false;
cout << “Input a target integer:”; cin >> y;
ifstream fin(“data.dat”);
while(fin >> x){
if(x == y){ flag = true; break; } }
if(flag) cout << y << “ exists in the data!”; return 0;
ファイル名の読み込み(P.56)
入出力に用いるファイルの名前をプログラム実行ごとに変更 したい ただ, 毎回実行前にプログラムのファイル名の部分だけ書き 直すのはとても面倒臭い ファイル名をキーボードからユーザが決定できるようにできる string型の変数 + c_str()メンバ関数 string filename;cout << “Input a filename -->”; cin >> filename;
ifstream fin(filename.c_str()); if(!fin){…}
ファイル名の読み込み(P.56)
string filename;
cout << “Input a filename -->”; cin >> filename;
ifstream fin(filename.c_str()); if(!fin){…}
string filename;
cout << “Input a filename -->”; cin >> filename;
ifstream fin(filename); if(!fin){…}
右のようには書けないので注意
ifstream, ofstreamはchar型の配列で初期化する必要がある obj.c_str()でstring型変数objからchar型配列を取り出せる
複数ファイルからのデータ入力(P.57)
#include<iostream> #include<fstream> #include<string> using namespace std; int main(){ const int sz = 3;string file[sz] = {“data1.dat”, “data2.dat”, “data3.dat”} for(int i = 0; i < sz; i++){
ifstream fin(file[i].c_str()); if(!fin){
cerr << “cannot open” << file[i] <<endl; continue;
} }