めんどくさいファイル入出力です。毎回忘れるので、いつも調べています。
[blogcard url=”https://qiita.com/NickTominaga/items/7e01b7eb0b67ac791ec6″]
さて、問題は複数のファイルを読み込みたい場合です。私の場合は連番のファイルを順番に読み込みたいというものでした。
さて、この場合だと、上のサイトのように書くとうまく動きません。
getline()が想定通りに動かないからです。よくわからない場所を取ってくる。
理由は、ファイルストームを閉じていないので、getline()が取ってくる行が前のファイルの続きみたいになるからだと思います。
例えば、前のファイルに10行あり、それを全部getlineしたとします。
そして、次のファイル(こちらも10行あるとする)を開いてgetlineさせようとします。
ファイルを開き直したからgetlineは1行目から読み取ってくれるだろと思いますが、getlineは11行目から取ろうとします。
しかし、10行しかないので、なにも読み取ってこない。
多分こんな流れだと思います。
想定通りに動いてないときの表示から推察したので間違えてるかもしれません。
じゃあ、どうすればいいかといえば、ファイルストームを閉じれば解決します。
ファイルストームの閉じ方は、
[cpp] reading_file.close(); [/cpp]を書くだけです。reading_fileの部分は、クラスの宣言部分で変わります。
ということで、サンプルコードを書きました。
#include <iostream> | |
#include <string> | |
#include <cmath> | |
#include <fstream> | |
#include <sstream> | |
using namespace std; | |
/*私の環境では、result1.txt,result2.txt・・・のように | |
連番にしていたので、順にファイル名を作成しています*/ | |
string make_filename(int a){ | |
string s = "result"; | |
string num = to_string(a+1); | |
s = s + num + ".txt"; | |
return s; | |
} | |
int main(int argc, char const *argv[]) { | |
ifstream reading_file; //クラス宣言。入力に使う。 | |
ofstream writing_file; //クラス宣言。出力に使う。今回は必要ない。 | |
for(int i = 0; i < 256; i++){ | |
string filename = make_filename(i); | |
reading_file.open(filename, ios::in); | |
cout<<filename<<endl; | |
string tmp; | |
getline(reading_file, tmp); //テストとして1行だけ取ってこさせる | |
cout<<tmp<<endl; | |
reading_file.close(); //ファイルストームを閉じる | |
} | |
return 0; | |
} |
参考:
[blogcard url=”https://docs.oracle.com/cd/E19205-01/820-2985/loc_io/9_2.htm”]
ifstreamは自動でファイルを閉じてくれるけど、ファイルストームは閉じてくれないので注意しなきゃいけない。
逆に、出力のときは何も考えずに、open()でファイルを開く→書き込む→open()でファイルを開く→・・・と書いて大丈夫です。
私はこれで1時間無駄にしました。