It's because you have text (China in the first instance) first in the file. You need to read the first word (China) into something first before you can go on reading the integers, I suggest reading China into a character array.
1 2 3
char array[20];
inFile >> array;
The above should read the first word (China) into the array. After you can go on reading the 3 numbers after into the different variables.
Yes, but that would only read the characters up to a whitespace (in the case of a country such as 'United States', this would only store 'United' in the character array).
Basically, I want to store the first line (whitespace or no) in a string, and the next 3 lines in integer containers. Is there any way I can do that with a while loop that stops once the EOF has been reached?
Another case of the sneaky new line character remaining in stream..
China
4873
91275
8363\n <- getline() is picking up a rogue newline character here which will result in an empty string
United States
324879
238172
3487
To ignore all newlines before and after your 4 lines of input:-
1 2 3 4 5 6 7 8 9 10 11
while (!inFile.eof())
{
if (inFile.peek() == '\n')
inFile.ignore();
else
{
getline(inFile, name);
inFile >> pop >> births >> deaths;
// cout << name << ", " << pop << ", " << births << ", " << deaths << endl;
}
}
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <vector>
usingnamespace std;
// Class declaration
class Country
{
private:
string name;
int pop,
births,
deaths;
public:
void setName(string n) {name = n;};
void setPop(int p) {pop = p;};
void setBirths(int b) {births = b;};
void setDeaths(int d) {deaths = d;};
string getName() const {return name;};
int getPop() const {return pop;};
int getBirths() const {return births;};
int getDeaths() const {return deaths;};
double getBirthRate();
double getDeathRate();
double getGrowthRate();
};
double Country::getBirthRate()
{return (double)births / pop;}
double Country::getDeathRate()
{return (double)deaths / pop;}
double Country::getGrowthRate()
{int newPop = pop - deaths + births;
return (1.0 - pop / newPop) * 100.0;}
int main()
{
string name;
int pop, births, deaths;
int i = 0;
vector<Country *> countries;
ifstream inFile;
inFile.open("pgm5.dat");
if (inFile)
{
while (!inFile.eof()) // While the end of file marker is not reached,
{
if (inFile.peek() == '\n')
inFile.ignore();
else
{
// Read in all information for that country
getline(inFile, name);
inFile >> pop >> births >> deaths;
}
// Create new vector element, point element to new Country object
countries.push_back(new Country);
// Store country information in Country object
countries[i]->setName(name);
countries[i]->setPop(pop);
countries[i]->setBirths(births);
countries[i]->setDeaths(deaths);
i++; // Increment vector counter
}
// Display vector contents
for (i = 0; i < (int)countries.size(); i++)
{
cout << countries[i]->getName() << endl
<< countries[i]->getPop() << endl
<< countries[i]->getBirths() << endl
<< countries[i]->getDeaths() << endl
<< countries[i]->getBirthRate() << endl
<< countries[i]->getDeathRate() << endl
<< countries[i]->getGrowthRate() << endl
<< endl;
}
}
else cout << "Error reading file.\n";
system("pause");
return 0;
}
Basically, I'm using a vector to assume that I don't know the number of blocks of information (country name, and 3 ints) that there are. So for each string encountered, I want to add that to an element in the vector, which contains pointers to class objects that I want to store the information in. I can't seem to get this to store the information and display it properly, though. Any thoughts/ideas?