Dawg Pwnd
Dawg Pwnd

Reputation: 1

Every other line of data is skipped when reading and storing data from a file

I'm new to C++ and I'm having a little trouble when it comes to reading lines of data from a text file. Let's say I have an unknown number of lines in a text file, with each line in the same format: int string double . The only thing that will be definite is a space will separate each piece of data on a given line. I'm using an array of structs to store the data. The code below works great except that it skips a line of input after each loop. I've tried inserting various ignore() statements and still can't get it to read each line, only every other line. If I rewrite some of the getline statements at the end, then the wrong data starts getting stored for the variables after the first loop.

Text file might look like this:

18 JIMMY 71.5
32 TOM 68.25
27 SARAH 61.4


//code
struct PersonInfo
{
    int age;
    string name;
    double height;
};
//..... fstream inputFile; string input;

PersonInfo *people;
people = new PersonInfo[50];

int ix = 0;
getline(inputFile, input, ' ');
while(inputFile)
{
    people[ix].age = atoi(input.c_str());
    getline(inputFile, input, ' ');
    people[ix].name = input;    
    getline(inputFile, input, ' ');
    people[ix].height = atof(input.c_str());

    ix++;

    getline(inputFile, input, '\n');
    getline(inputFile, input, ' ');
}

I'm sure there are more advanced ways to do this, but like I said I'm pretty new to C++ so if there are just some slight modifications to the code above, that would be great. Thanks!

Upvotes: 0

Views: 2362

Answers (2)

Mooing Duck
Mooing Duck

Reputation: 66922

You've made this whole code ridiculously complicated.

struct PersonInfo
{
    int age;
    string name;
    double height;
};

std::vector<PersonInfo> people;
PersonInfo newPerson;
while(inputFile >> newPerson.age >> newPerson.name >> newPerson.height)
    people.push_back(std::move(newPerson));

Your problem is because first your read each bit of data one at a time from the file, then a whole line from teh file, then each bit of data one at a time from the file again. Maybe what you intended was more like this?

std::string fullline;
while(std::getline(inputFile, fullline)) {
    std::stringstream linestream(fullline);
    std::getline(linestream, datawhatever);
    ....
}

By the way, more idiomatic code might look like more like this:

std::istream& operator>>(std::istream& inputFile, PersonInfo& newPerson) 
{return inputFile >> newPerson.age >> newPerson.name >> newPerson.height;}

{ //inside a function
    std::ifstream inputFile("filename.txt");

    typedef std::istream_iterator<PersonInfo> iit;
    std::vector<PersonInfo> people{iit(inputFile), iit()}; //read in
}

Proof it works here

Upvotes: 1

taocp
taocp

Reputation: 23634

You can do the file reading as follows:

int ix = 0;
int age = 0;
string name ="";
double height = 0.0;
ifstream inputFile.open(input.c_str()); //input is input file name

while (inputFile>> age >> name >>  height)
{
  PersonInfo p ={age, name, height};
  people[ix++] = p;
}

Upvotes: 1

Related Questions