第 2 回:ファイル入出力

プロジェクト演習Ⅳ・Ⅵ
インタラクティブゲーム制作
第2回
ファイル入出力
今日の内容
• ファイルの読み書きができるようになろう
– もうパラメータとかをプログラム中で
ゴリゴリ代入するのはまっぴらだ!
– 「ハードコーディング」と言われて、
現場では忌み嫌われる行為
読み書きのターゲットは
• とりあえずテキストファイル
– 特にCSVやタブ区切りテキストは扱えると
超便利
• マップデータ、キャラクタパラメータ、
シナリオデータ、セーブデータなどなど
• 「テキストファイルとか見られたら
恥ずかしいし…」とか言うのは後だ!
とりあえず使うもの
• C++の標準機能だけでやってみよう
– 読み込みは「ifstream」
– 書き込みは「ofstream」
• インクルードは以下の通り
– #include <iostream>
– #include <fstream>
– 両方必要なので気をつける
• 必要に応じてusing namespace std;も
書き込みは絶望的に簡単だ!
• インスタンス生成時
にファイル名指定
• is_open()で開けてい
るかチェック
• <<で書き込むデータ
を繋げて流し込む
• 最後はclose()
ofstream out_file(“ファイル名”);
if(out_file.is_open() == false) エラー処理;
out_file << “書き込みたい文字” << endl;
// int値やdouble値も<<で繋いで書ける
// もちろんstring型やchar型もOK
out_file << x << “,” << y << endl;
//書き込み終わったらcloseして終了
out_file.close();
読み込みも
ただ読み込むだけなら簡単だ!
• インスタンス生成時
にファイル名指定
• is_open()で開けて
いるかチェック
• getlineで1行ずつ
取り出し、必要に
応じて処理する
• 最後はclose()
ifstream
string
vector<string>
in_file(“ファイル名”);
lineStr;
readBuffer;
if(in_file.is_open() == false) エラー処理;
// 1行ずつwhileループで読み出す
while(getline(in_file, lineStr) == true) {
// lineStrに1行分入る
// とりあえず配列にしまうならこう
readBuffer.push_back(lineStr);
}
in_file.close();
結局何が面倒って
• 読み込んだ後の文字列処理なんです
• C++のstringクラスはJavaに比べると
機能が正直貧弱です
• 最低限のものは揃っているので、うまく
素材を組み合わせて関数を作ろう
– サンプルあります
• データを取り出しやすいファイル構造を
作ろう
区切り取り出し関数実装例
vector<string> fk_StrSplit(string argStr, string argToken)
{
vector<string>
retStrArray;
string::size_type curPos = 0, nextPos = 0;
while(nextPos != string::npos) {
nextPos = argStr.find(argToken, curPos);
retStrArray.push_back(argStr.substr(curPos, nextPoscurPos));
curPos = nextPos+argToken.size();
}
return retStrArray;
}
区切って取り出す
• fk_StrSplit()関数
– JavaのStringクラスのsplit()のようなもの
– 正規表現は使えないけどカンマ区切り、
タブ区切り程度なら対応可能
• カンマ区切り、タブ区切りはExcelでの
編集が容易なので、出来ておいて損は
ない
– マップやシナリオのエディタをExcelで
代用しているソフトハウスもあります
整数値・実数値変換
• Cの標準関数をなんだかんだで使う
– atoi()がInteger.parseInt()にあたる
– atof()がDouble.parseDouble()にあたる
• ただしstring型の変数は直接引数に
渡せないので、c_str()関数を使う
– atoi(anyStr.c_str())のようにする
• 実数値は誤差に厳しいものだと変換時に
値がズレることがあるので注意
ファイル形式の作り方のコツ
• FK Performerのモーションデータなどを
見てみるとよい
• 「ファイルヘッダ」は必ず付けると
– ファイルの先頭でファイルの種類が
識別できるようにする
• [BEGIN]~[END]で囲っておくと、
データを読み込むべき範囲が
分かりやすくなるので処理しやすい
ファイル入出力のクラス化例
• fkut_ConfigDataクラス
– 「A=B」という記述形式を読み書きすること
に特化したクラス
– 元々はパッドのコンフィグデータ用に作った
が、パラメータ調整などにも使えそう
– ここまでの資料をもとにソースを読み解いて
みると良いかも
読み込み内容に基づく
データ生成
• 例えば読み込んだデータに基づいて
立方体を配置するプログラムを考える
• 個数が固定ならいいが、そうではない
ケースの方が圧倒的に多い
• クラスオブジェクトの動的な生成が必須
今日の課題
• CSVテキストに基づいて、3D空間中に
立方体を配置するプログラムを作れ
– ファイル形式も自分で決める
– 位置、姿勢、大きさはデータによって決定
– 立方体の個数は任意(ファイル内容次第)
– マテリアルも指定できるならそれもよし
• 1行の文字列から””で囲まれた文字列を取
り出す関数を作れ