C++のストリーム・ファイル入出力 streamとfstream

#include <iostream>

using namespace std;

int main( )
{
  cout << "abc" << endl;

  return 0;
}

C++でファイル入力出力には,fstreamを使う。
ifstreamクラスでファイルから入力
ofstreamクラスでファイルへ出力する

私が実際にifstreamやofstreamを使うときのコードを紹介します。

-----------------------------------
// ファイルから読み出したものを画面に全て出力
#include <fstream>
#include <string>

#include <iostream>

using namespace std;

int main( )
{
  ifstream ifs("data.txt");
  string buf;

  while(ifs && getline(ifs, buf)) {
    cout << buf << endl;
  }

  return 0;
}
------------------------

while(ifs && getline(ifs, buf))
について
ifs を最初につけているのは,ファイルを開くのを失敗したかどうかの点検
getlineは,ifs.getline( ) と同じ機能で,ifsで開いたファイルから1行読み込む
これも,whileの内側に入れておけば,読み込み終了や,読み込み失敗時に
自動的にwhileのループから抜ける。

常に string型で1行読み込めは,文字列の長さが長すぎる場合(char配列のときの配列長が足りない場合)とか,数値読み込み予定で文字列が来たときの対処に強くなる。外部にあるファイルなんて,実際どんな内容が書いてあってもおかしくないので,問題対策にも強い。

具体的には,以下のコードは使わないということだ。

int a;
char b[10];
ifstream ifs("data.txt");

ifs.getline(b, 9); // char型でgetline 9文字以上は,ややこしい。
ifs >> a; // 数値がこないと,読み込まない=>不安定になる。


実際のプログラムで「ファイルを開くことが出来ませんでした」とか
「データの読み込みに失敗しました」等を表示しても,ユーザは
困るだけである。このメッセージで対処出来る人は,そこそこ知識がある人。
また,知識がある人なら,メッセージが出なくても,ある程度推測できる。

そのため,エラーメッセージは出さず,ファイルがないなどのエラーが起こっても
問題ない様に「セーフモード」を用意しておいて動作し続けるコードの方が
現実的である。まぁ,「ファイルがない」か,「ファイルが壊れている」ぐらいは,
知らせたほうが良いかも。


ファイルへの書き出し

-----------------------------------
// ファイルから読み出したものを画面に全て出力
#include <fstream>

using namespace std;

int main( )
{
  ofstream ofs("data.txt");
  string buf;

  if(ofs) {
    ofs << "OK" << endl; // cout に書き出すのと同じ感じで
  }

  return 0;
}
------------------------


ファイルの開いている範囲を限定する



-----------------------------------
// ファイルから読み出したものを画面に全て出力
#include <fstream>

using namespace std;

int main( )
{
  {
    ofstream ofs("data.txt");
    string buf;

    if(ofs) {
      ofs << "OK" << endl; // cout に書き出すのと同じ感じで
    }

  } // ここまでくれば, ofs はofs.close();が自動実行される。


  
  ofstream ofs("data.txt");
  string buf;

  if(ofs) {
    ofs << "OK" << endl; // cout に書き出すのと同じ感じで
  }


  {
    ifstream ifs("data.txt");
    string buf;

    while(ifs && getline(ifs, buf)) {
      cout << buf << endl;
    }
  } // ここまでくれば, ifs はifs.close();が自動実行される。

  return 0;

}
------------------------

ブロック { } を使い,ファイルの開いている範囲を明確に出来るし,
ifs.close( ) ;を書かなくて済む。

また,{ } の外では,絶対に閉じられたファイルへのアクセスが無いので,
ファイルが閉じられてアクセスできなくなっても,絶対に
ファイルの読み書きを実行しないことが,保障される。

また,コンストラクタでopenしデストラクタでcloseするようにしたほうが,
open( )メンバ関数や,close( )メンバ関数を使うより,オブジェクト指向的にスマートだ。


ファイル入出力のオプション
バイナリモードと追加書き込みモード


これらの,オプションの指定するためのものはios_baseクラスに入っています。
#include <ios> で使えます。(※明確にincludeしなくてもストリーム系のヘッダファイルはどれも#include <ios>しているので,書かなくても問題ありません)

ios_base::なんとか で使う

ifstream ifs("でーた.dat", ios_base::binary | ios_base::in);
でifsでバイナリモードでオープン。 メンバ関数openでも,同様

ofstream ofs("でーた.dat", ios_base::binary | ios_base::out | ios_base::trunc );
でofsバイナリモードで新規作成書き出し。 メンバ関数openでも,同様

ofstream afs("追記でーた.dat", ios_base::out | ios_base::app );
でofsでファイルがあれば,追記書き込み。無ければ作成

詳細;
ios_base::in : 読み込みモード
ios_base::out : 書き出しモード
ios_base::trunc : 新規作成する(ファイルがあれば,先に消去する)
ios_base::app : 各挿入前にストリームの終端へ移動(追加書き込み)
ios_base::binary : バイナリモードで開く

"C++のストリーム・ファイル入出力 streamとfstream" へのコメントを書く

お名前
メールアドレス
ホームページアドレス
コメント