2012年12月22日土曜日

ifstream でテキストファイルを読み込む場合のあれこれ

ファイル名の指定

C++11から,std::stringが直接使えるようになったが,
C++11以前は const char * のみ.

std::string filename("hoge.txt");
std::ifstream f(filename.c_str());

ファイルが正しく開いたかのチェック

bad()ではダメで,fail()を使う.あるいは,!f でもよろしい.
! 演算子は fail と同じ.
http://en.cppreference.com/w/cpp/io/basic_ifstream
しかし,宣言だけしてファイルを開く処理を行っていない場合(うっかり忘れている場合)も fail() は false なので,結局,is_open() ファイルオープンの検査には最良か.


順に,宣言だけ,ファイルあり,ファイルなし

f true,true,false
f.bad() false,false,false
f.fail() false,false,true
f.good() true,true,false
f.is_open() false,true,false



また当然の挙動であるが,

f.eof() false,false,false

たとえ,サイズ0バイトのファイルを開いても,f.eof()はtrueにならない(読み込み処理を一度でも行わないとフラグが立たないと思われる.まあそれはそうだろう).


以下,テスト用のコード:

  std::ifstream f;
  f.open("sample.txt");

  if (f) {
    std::cout << "f" << std::endl;
  }
  if (f.fail()) {
    std::cout << "f.fail" << std::endl;
  }
  if (f.bad()) {
    std::cout << "f.bad" << std::endl;
  }
  if (f.good()) {
    std::cout << "f.good" << std::endl;
  }
  if (f.is_open()) {
    std::cout << "f.is_open" << std::endl;
  }
  if (f.eof()) {
    std::cout << "f.eof" << std::endl;
  }

ファイルから1行 string に読み込む

ifstreamのメンバ関数ではなくて,std::getline を使う.
行末の改行は削除される.

#include <fstream>
#include <string>

std::ifstream f("sample.txt");
std::string s;
std::getline(f, s);


ファイルの終端に達したかチェックする

f.eof()を使ってwhileでくりかえせばよい.
1行ずつ読み込んでから解釈するのであれば,これで十分.

0 件のコメント:

コメントを投稿