マップファイルを外から読み込みたい欲がある
読み書きそろばん!
ってことで、書いたら次は読んでみる
ややこしくなるので、前準備としてまずは新しいプロジェクトを準備しよう
Siv3Dでまた簡素版のテンプレでプロジェクトを作ろう
そんで、とりあえずみんなVSの上から実行すると思うので、VSから実行時のカレントディレクトリに読み込み用のファイルを仕込む
- "input.txt"
Dorothy lived in the midst of the great Kansas prairies, with Uncle Henry, who was a farmer, and Aunt Em, who was the farmer's wife. Their house was small, for the lumber to build it had to be carried by wagon many miles. There were four walls, a floor and a roof, which made one room; and this room contained a rusty looking cookstove, a cupboard for the dishes, a table, three or four chairs, and the beds.
これをメモ帳とかでinput.txtとして保存して、カレントディレクトリに置く
(文章は「オズの魔法使い」の冒頭)
ファイルを読んでいく
読み込みの時も、手順は書き込みと変わらない
ファイルオープン⇒好きなように読み込み⇒終わったらクローズ
である。あとは、データファイルの作り方(設計)がよいか悪いか、ストリームの扱いがうまいか下手かで、読み込み出来たりできなかったりになってくる。
今回は、データファイルを見ると、1行に1文書いてある英文である。(ここで言う1行は、ファイル上の区切り=“\n”改行コードが出てくる部場所までのこと)
じゃぁ、まずなにかしら読み込んで、コンソールに表示してみよう。
- "Main.cpp
# include <Siv3D.hpp> // OpenSiv3D v0.6.10 # include <filesystem> # include <string> #include <fstream> using std::cout; using std::endl; using std::string; using std::ifstream; //名前空間インプットファイルストリームを使うよ void Main() { ifstream input_file; //入力ファイルストリーム string fname = "input.txt"; //ファイル名を指定 input_file.open(fname, std::ios::in);//ストリームを入力モードでオープン if (input_file.fail())//エラー処理は大事 { cout << "ファイルオープンに失敗" << endl; exit(0); } string indata; //こいつに1行分読み込むよ input_file >> indata; //cin的に使えるんでしょ?じゃあこうだ Console.open(); cout << indata; input_file.close(); while (System::Update()) { } }
結果はどうなっただろう。。。ドロシー。。。
Dorothyしか表示されないね。これはcinの時もそうだったけど、複数の値を入力するときにスペースで区切って入力したよね。
int a,b,c cin >> a >> b >> c; //12 23 24
これと一緒で、デフォルトの状態では、スペースや改行はデータの区切りとしてとらえらえてしまうんだなぁ。
そこで1行入力!
- "Main.cpp"
//input_file >> indata; //cin的に使えるんでしょ?じゃあこうだ //これを std::getline(input_file, indata); //inputファイルストリームから一行入力
無事一行表示できたかな?
そしたらこれを全行表示してみよう。
std::getline()は読み込みデータがなくなるとEOFというデータを返す。
このデータはなぜかfalseの代わりにwhile文を抜けられるので以下のように書いてみる
- "Main.cpp"
Console.open(); //input_file >> indata; //cin的に使えるんでしょ?じゃあこうだ //これを //std::getline(input_file, indata); //inputファイルストリームから一行入力 //これをさらに while (std::getline(input_file, indata)) { cout << indata; getchar(); } //下のcoutはwhile内に移動したので消す
一行ずつ最後まで読み込めただろうか?
これで、ファイル書き込みと読み込みの基本はできたということになる。
Missions
- プログラムを実行して、ファイルが読み込めているかどうかを確認
- ファイルオープンが成功したら(分岐が必要)絶対パスが取得できるので
- std::filesystem::path absPath;を宣言しておいて
- absPath = std::filesystem::absolute(fname);
- で、オープンしたファイルの絶対パスを取得し、コンソールにファイルの絶対パスを表示してみよう
- カレントディレクトリを移動して、実行ファイルの場所を移動した時に読み込みファイルとの関係がどうなるか確認