Each line is prefixed by the type of object.
So your reader should read the first word off and then decide what object to read.
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);}
}
For each type of object you need to define a structure to hold the data.
// 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;
};
Now you have to define a method to read the data. In C++ we use operator>>
to read data from a stream.
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;
}
Repeat the processes for the other types you need to read. Then writting the read commands becomes simple:
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.
}
Repeat the processes for the other types.