Reputation: 826
Apologies if this is a really simple question but I'm fairly new to C++ and I'm having trouble with a project I'm working on.
Part of this project involves writing the information of an object to a .txt file and being able to read that .txt file to load in an object. (In this case the information is written rather than the object itself so that someone can easily edit the .txt to change an object).
The function I'm calling to read from the .txt file is as follows:
void Room::load(ifstream& inFile)
{
string garbage;
string str;
inFile >> garbage >> garbage >> mId;
inFile >> garbage; getline(inFile, mName);
inFile >> garbage; getline(inFile, mDesc);
loadVec(garbage, inFile, mExits);
}
"garbage" being used to get rid of descriptors in the .txt to help a user.
A typical room object should look something like the following:
Room ID: 2
Name: Foyer
Description: The player can enter here from the kitchen.
Exits: 3 4
My problem occurs when I try to load multiple Rooms. The first Room will load perfectly but any subsequent Room will fail to load properly.
I would have at least expected it to fail in such a way as the first room in the .txt file is loaded repeatedly but that isn't the case.
I'd be very grateful for any help anyone could offer, thanks in advance.
Edit: For now I'm loading rooms using the following code:
if (inFile)
{
//Assign data to objects
room0.load(inFile);
room1.load(inFile);
}
In this case, room0 winds up with the data of the first room in the .txt file but room1 remains unchanged with the exception of having its exits cleared for some reason.
Testing the program at the moment gives the following:
BEFORE LOAD
ID= -1
NAME= Nowhere
DESC= There's nothing here.
Exits= -1
ID= -1
NAME= Nowhere
DESC= There's nothing here.
Exits= -1
AFTER LOAD
ID= 1
NAME= Kitchen
DESC= This is the first room the player will see.
Exits= 2 3 5 6
ID= -1
NAME= Nowhere
DESC= There's nothing here.
Exits=
Press any key to continue . . .
Those rooms being room0 and room1 respectively both before and after load.
Here's what the loadVec function looks like:
//Loads consecutive integers from inFile, saving them to vec
void loadVec(string& garbage, ifstream& inFile, vector<int>& vec)
{
int num;
vec.clear();
inFile >> garbage >> num;
vec.push_back(num);
while (inFile)
{
inFile >> num;
vec.push_back(num);
}
vec.erase(vec.begin() + vec.size() - 1);
}
And the unedited .txt file from which the program should be loading:
Room ID: 1
Name: Kitchen
Description: This is the first room the player will see.
Exits: 2 3 5 6
Room ID: 2
Name: Foyer
Description: The player can enter here from the kitchen, they can exit to the rooms with the IDs listed as 'Exits'.
Exits: 3 4
Room ID: 3
Name: Bathroom
Description: This is the third room.
Exits: 4
Upvotes: 1
Views: 2278
Reputation: 409404
The problem is that after you have read the exits, the streams failbit
is set. As long as it's set it will not read anything.
You will have to call std::istream::clear
to clear the error.
By the way, there is a more C++-ish way to read into a vector:
std::copy(std::istream_iterator<int>(inFile),
std::istream_iterator<int>(),
std::back_inserter(vec));
References:
You do of course have to read the "tag" (garbage
) first before doing this.
Upvotes: 2