マップファイルを外から読み込みたい欲がある
せっかくエクセルでマップを作れるようになったし。
そろそろファイルを外から読み込んでみたいよね。
実行ファイル←マップファイル
これができると、マップが少しよろしくないなぁ。と変更したときにもプログラム側には変更は必要なくなり、マップファイルだけを修正すれば変更が完了する。
このように、プログラミングの基本的な考え方として、「データとプログラムの分離」というのが、だんだん大事になってくる。
ファイル読み込みの手順
- ファイル
- 書き込み(write)
- オープン(ファイル指定、モード指定(しないとtext?))
- オープン時には、指定したファイルをカレントディレクトリで検索
- 書き込み
- クローズ
- 読み込み(read)
- オープン(ファイル指定、モード指定)
- オープン時には、指定したファイルをカレントディレクトリで検索
- 読み込み
- クローズ
つまり、読み込みも書き込みも、カレントディレクトリ(これはLinuxの授業で習ったから大丈夫だよね?)にあるファイルを指定して、オープン処理、読み込み処理、必要なくなったら、クローズする。という手順が必要である。
カレントディレクトリの取得
それではまず、カレントディレクトリを取得してみよう。
最新のC++(C++20ぐらい)では、std::filesystemというすんばらしい機能が追加された。
これは、カレントディレクトリの取得や、ファイルの操作(読み書きは除く)が、C++の機能だけでOSによらず統一的にできるようになったというありがたいアップデートである(ってことは、今まではOS別で別々のプログラム書いてたんだよ。まぁいまでも書いてるからしばらくはソースコードのほうがアップデートされないと思うんだけどね)。
じゃぁやってみよう。まずSiv3Dのプロジェクトを簡素版のほうのテンプレで作ろう。
Visual Studio+Siv3Dはファイル操作に関してはちょいとめんどくさいことがあるので、初めにこれを覚えておこう。
- Siv3D以外の自分で作ったプロジェクト
- VisualStudio上から、デバッグボタンでプログラムを起動したとき
- カレントディレクトリは、プロジェクトファイル(.proj)があるフォルダ
- コンパイルしたプログラム(実行ファイル)をダブルクリックで起動したとき(自分でファイル指定したとき)
- カレントディレクトリは、実行ファイルがある場所
- Siv3Dのプロジェクト
- VisualStudio上から、デバッグボタンでプログラムを起動したとき
- カレントディレクトリは、プロジェクトファイル(.proj)があるフォルダの下のAppフォルダ
- コンパイルしたプログラム(実行ファイル)をダブルクリックで起動したとき(自分でファイル指定したとき)
- カレントディレクトリは、実行ファイルがある場所
このめんどくさいルールを確認してみよう。
Siv3Dのテンプレに以下のプログラムを追加
std::filesystem::path はパスを表す文字列だが、コンパイルした環境に合わせた文字コードを使って結果を返してくる(のが、便利なのか厄介なのかよくわからん)。
カレントディレクトリは、 std::filesystem::current_path()関数で取得できる、戻り値の型はstd::filesystem::path形式である。
実はこれにはとてもありがたい機能がついている。
std::filesystem::path crrpath = std::filesystem::current_path();
このコードで、crrpathにカレントパスを取得したとき以下の関数が使える。
crrpath.string(); //C++文字列に変換 crrpath.wstring(); //C++ワイド文字列に変換 crrpath.generic_u8string(); //UTF-8形式に変換 crrpath.generic_u16string(); //UTF-16形式に変換 crrpath.generic_u32string(); //UTF-32形式に変換
Siv3DはU““って文字列を使ってるよね。これは実はUTF-32形式を使っている。
なので、出力するときにどれを使えばいいかはわかるよね!
カレントディレクトリ取得のソースコード
- "Main.cpp"
# include <Siv3D.hpp> #include <filesystem> //std::filesystemを使うのに必要 void Main() { //カレントディレクトリ取得 std::filesystem::path crrpath = std::filesystem::current_path(); Font font{ 30 }; while (System::Update()) { font(ここでUTF32に変換してフォントに渡す).draw(Vec2{ 10,Scene::Center().y }, Palette::White); } }
まずは、Visualstudioの上から実行してみよう。
んで、つぎに、ソリューションエクスプローラーのプロジェクト名のところを右クリック⇒エクスプローラーでフォルダを開く⇒Appフォルダを開く⇒その中に****.exeがある。これがみんなが作った実行ファイルである。
これをデスクトップあたりに移動して実行してみよう。
結果がどう変わるか確認出来たらOK