各行には、オブジェクトのタイプが接頭辞として付けられます。
したがって、読者は最初の単語を読み上げてから、どのオブジェクトを読み取るかを決定する必要があります。
std::ifstream file("data.txt");
std::string type;
while(file >> type)
{
if (type == "info") { readInfo(file);}
else if (type == "common") { readCommon(file);}
else if (type == "chars") { readChars(file);}
else if (type == "char") { readChar(file);}
}
オブジェクトのタイプごとに、データを保持するための構造を定義する必要があります。
// char id=32 x=837 y=15 width=3 height=1 xoffset=-1 yoffset=31 xadvance=8 page=0 chnl=15
struct CharData
{
int id;
int x;
int y;
int width;
int height;
int xoffset;
int yoffset;
int xadvance;
int page;
int chnl;
};
次に、データを読み取るメソッドを定義する必要があります。C++ ではoperator>>
、ストリームからデータを読み取るために使用します。
std::istream& operator>>(std::istream& stream, CharData& data)
{
// All the data is on one line.
// So read the whole line (including the '\n')
std::string line;
std::getline(stream, line);
// convert the single line into a stream for parsing.
// One line one object just makes it easier to handle errors this way.
std::stringstream linestream(line);
// Assume the prefix type information has already been read (now looks like this)
// id=32 x=837 y=15 width=3 height=1 xoffset=-1 yoffset=31 xadvance=8 page=0 chnl=15
std::string command;
while(linestream >> command) // This reads one space separated command from the line.
{
if (command.substr(0,3) == "id=") {data.id = atoi(&command[3]);}
else if (command.substr(0,2) == "x=") {data.x = atoi(&command[2]);}
else if (command.substr(0,2) == "y=") {data.y = atoi(&command[2]);}
else if (command.substr(0,6) == "width=") {data.width = atoi(&command[6]);}
else if (command.substr(0,7) == "height=") {data.height = atoi(&command[7]);}
else if (command.substr(0,8) == "xoffset=") {data.xoffset = atoi(&command[8]);}
else if (command.substr(0,8) == "yoffset=") {data.yoffset = atoi(&command[8]);}
else if (command.substr(0,9) == "xadvance=") {data.xadvance = atoi(&command[9]);}
else if (command.substr(0,5) == "page=") {data.page = atoi(&command[5]);}
else if (command.substr(0,5) == "chnl=") {data.chnl = atoi(&command[5]);}
}
return stream;
}
読み取る必要がある他のタイプについて、このプロセスを繰り返します。次に、読み取りコマンドの書き込みが簡単になります。
std::vector<CharData> charVector;
void readChar(std::istream& stream)
{
CharData data;
stream >> data; // read the object from the stream
// This uses the `operator>>` we just defined above.
charVector.push_back(data); // put the data item into a vector.
}
他のタイプについても同じ手順を繰り返します。