🐈
[C++] ファイル入出力の覚書
何回やっても覚えられないし、
いちいちネットであちこち調べるのが面倒なので
自分がよく使う入出力をまとめておく。
C++の場合、使うクラスは
ifstream, ofstreamの2つの種類があり、
ifstream, ofstreamのiが入力、oが出力を表す。
fstreamをインクルードすることで両方使える。
読み込み、書き込みの際、
モードについても抑える必要がある。たとえば
読むときは以下のようにモードを指定する。
(ここでは、「読み取り専用モード」で開いている)
reading_file.open(filename, std::ios::in);
#入力
ファイルを読み込んで、ある区切り文字(デリミタ)で
一行ずつ読む場合は以下のようにする。
モード | 意味 |
---|---|
ios::ate | 開く時にEOFまで移動する |
ios::binary | ファイルをバイナリモードで開く |
ios::in | 読み込み専用で開く |
よく使うのは、eof()メソッドで、
読み込んでいるファイルが終端まで来たときに、制御を変えることができる。
#include <iostream> // for debug writing
#include <string> // useful for reading and writing
#include <fstream> // ifstream, ofstream
#include <sstream> // istringstream
int main(int argc, char** argv)
{
std::string filename = argv[1];
std::ifstream reading_file;
reading_file.open(filename, std::ios::in);
std::string reading_line_buffer;
std::cout << "reading " << filename << "..." << std::endl;
while (!reading_file.eof())
{
// read by line
std::getline(reading_file, reading_line_buffer);
std::cout << reading_line_buffer << std::endl;
// read by delimiter on reading "one" line
const char delimiter = ' ';
std::string separated_string_buffer;
std::istringstream line_separater(reading_line_buffer);
std::getline(line_separater, separated_string_buffer, delimiter);
std::cout << separated_string_buffer << std::endl;
}
}
ファイルを読むときは、上述のように
クラスを宣言してからopenメソッドで読んでもよいが、
以下のように、コンストラクタを使って一気に読み込んでもよい。
std::ifstream reading_file(filename, std::ios::in);
#出力
モード | 意味 |
---|---|
ios::out | 出力用にファイルを開く |
ios::app | 追加出力 |
ios::trunc | 既存のファイルを上書きする |
#include <iostream>
#include <string> // useful for reading and writing
#include <fstream> // ifstream, ofstream
int main()
{
std::string filename = "test.txt";
std::ofstream writing_file;
writing_file.open(filename, std::ios::out);
std::cout << "writing " << filename << "..." << std::endl;
for (int i = 0; i<10; i++)
{
writing_file << i << std::endl;
}
}
#補足
読みこみ・書き込み失敗が
メンバ関数fail()で確認できるので、その
エラー処理を適宜入れるのがよい。
#ややこしい話
fstreamにはメンバ関数getline()があるが、
使えないので基本的に使わない。
代わりに、上で示したように、
STLのstringにあるgetline()を使う。
#TIP
空白が連続していて、読みづらいファイルの場合、
演算子>>を使う。
たとえば、
std::string separated_string_buffer = "";
std::istringstream line_separater(reading_line_buffer);
line_separater >> separated_string_buffer;
line_separater >> separated_string_buffer;
line_separater >> separated_string_buffer;
とすると、空白を飛ばして読める。
Discussion