2014年06月07日

C++ メモランダム (ifstream)

相変わらず急に雨が降りだしたりして不安定な天気です。体の方もいまいち調子悪いです。

プログラムに渡すデータを標準入力とファイルの両方からに対応したい場合、C 言語で fopen 等を使う場合は

FILE* fp;
char* fileName;
  :
if ( fileName != NULL ) {
  if ( ( fp = fopen( fileName, "r" ) ) == NULL ) {
    fprintf( stderr, "can't open file %s.\n", fileName );
  }
} else {
  fp = stdin;
}

とすれば可能ですが、C++ で入力ストリームを使う場合

std::ifstream ifs;
string fileName;
  :
if ( ! fileName.empty() ) {
  ifs.open( fileName.c_str() );
  if ( ! ifs ) {
    std::cerr << "can't open file << fileName << std::endl;
  }
} else {
  ifs = std::cin;
}

とはできないんですよね。std::cin は std::ifstream の基底クラス std::istream なのでそのままでは代入ができないわけです。このときは、

std::ifstream* ifs;
string fileName;
  :
if ( ! fileName.empty() ) {
  ifs = new std::ifstream( fileName.c_str() );
  if ( ! *ifs ) {
    std::cerr << "can't open file << fileName << std::endl;
  }
} else {
  ifs = &( std::cin );
}

とポインタ (または参照) を使えば解決します。以前にも同じことで悩んで調べるハメになってしまったので、忘れないようにメモしておきます。