Problem loading object data from text file
Why doesn't this code want to load all the values from a text file? It only loads the first object's items correctly but after that it starts going weird. Here is the code:
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
class Location
{
public:
Location()
{
locName = "No Name";
locDesc = "No Description";
locID = 0;
}
friend os开发者_JS百科tream& operator <<(ostream& outs, const Location & showMe)
{
// keeping output same as input...
outs << showMe.locName << endl;
outs << showMe.locDesc << endl;
outs << showMe.locID << endl;
return outs;
}
friend istream& operator >>(istream& ins, Location & inLoc)
{
getline(ins, inLoc.locName);
getline(ins, inLoc.locDesc);
ins >> inLoc.locID;
return ins;
}
private:
string locName;
string locDesc;
int locID;
};
int main()
{
ifstream inFile;
inFile.open("loc_data.txt");
if (inFile.fail())
{
cout << "\nCould not open the input file!";
exit(1);
}
Location fileLoc[10];
int i = 0;
while (inFile.good())
{
inFile >> fileLoc[i];
i++;
}
for (int j = 0; j < 10; j++)
cout << fileLoc[j];
return 0;
}
The input file is:
Town Hall
Main venue for functions
1
City Park
Outdoor venue
2
Train Station
Commuting point
3
Local Airport
Long distance travel
4
And the output is:
Town Hall
Main venue for functions
1
City Park
0
No Name
No Description
0
No Name
No Description
0
No Name
No Description
0
No Name
No Description
0
No Name
No Description
0
No Name
No Description
0
No Name
No Description
0
No Name
No Description
0
I have a suspucion that getline is responsible for this but do not know enough to be sure, however I would really like to know why this is happening and not just a 'fix'.
Your first problem is that this line doesn't extract the newline character:
ins >> inLoc.locID;
This means that the getline
in for the second Location
is extracting the rest of the line after 1
- i.e. an empty string - for the name.
This means that you are quickly getting out of sync with the lines that you want to read.
You should also consider changing your while loop, as it stands you check whether the stream is "good" before extracting a new location but you do not check whether the extraction was successful, you assume that the extraction works.
This works:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <sstream>
using namespace std;
class Location
{
public:
Location()
{
locName = "No Name";
locDesc = "No Description";
locID = 0;
}
friend ostream& operator <<(ostream& outs, const Location & showMe)
{
// keeping output same as input...
outs << showMe.locName << endl;
outs << showMe.locDesc << endl;
outs << showMe.locID << endl;
return outs;
}
friend istream& operator >>(istream& ins, Location & inLoc)
{
getline(ins, inLoc.locName);
getline(ins, inLoc.locDesc);
std::stringstream ss;
std::string s;
getline(ins, s);
ss << s;
ss >> inLoc.locID;
return ins;
}
private:
string locName;
string locDesc;
int locID;
};
int main()
{
ifstream inFile;
inFile.open("loc_data.txt");
if (inFile.fail())
{
cout << "\nCould not open the input file!";
exit(1);
}
Location fileLoc[10];
int i = 0;
while (inFile.good())
{
inFile >> fileLoc[i];
i++;
}
for (int j = 0; j < 10; j++)
cout << fileLoc[j];
return 0;
}
I believe the issue is with this line: ins >> inLoc.locID;
The problem is that when you read this value in with the >> operator it is leaving the next line charactor in the buffer, this then causes the read loop to end (as can be seen if you step through it).
To get around this i think you need to purposely empty this charactor from the buffer or use getline and convert the input (with validation i would hope!) to a number from a string.
Hope this helps,
精彩评论