0

I am trying to read in data from a .txt file and use it to create several instances of a struct. I want to do this progromatically via code, as opposed to declaring each instance of the struct manually in a pre determined way (I want it to work for any number of structs being created/data rows in the input file).

The input file contains a name and then three doubles. Each new line is a new person ("input.txt"):

Peter 1.0 2.0 3.0
James 4.0 5.0 6.0

Code:

struct Person 
{
  string name;
  vector<double> numbers;
};


int main()
{

ifstream inStream("input.txt");

vector<Person> vecPerson; // vector to hold structs
string nameInput;
double num1;
double num2;
double num3;

int i =0;
while( inStream.peek() != EOF )
{

    inStream >> nameInput >> num1 >> num2 >> num3; //read in data to variables

    //create struct
    Person person[i];
    person[i].name = nameInput;
    person[i].numbers[0] = num1;
    person[i].numbers[1] = num2;
    person[i].numbers[2] = num3;
    i++;

    vecPerson.push_back(person[i]);
}  

This code gives a segfault. The line Person person[i]; clearly isn't right syntactically. I am not sure how I create a different name for the struct instance for each loop of the while loop.

How do I do this?

Reno
  • 831
  • 3
  • 10
  • 18
  • rewmove all of the `[i]`'s in your code. You only need a single person in the for loop, not an array of them. – NathanOliver May 26 '20 at 16:50
  • How does each struct have a different name then? – Reno May 26 '20 at 16:51
  • 1
    You should also replace `while( inStream.peek() != EOF )` with `while (inStream >> nameInput >> num1 >> num2 >> num3;)`. See this for why: https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons – NathanOliver May 26 '20 at 16:51
  • 1
    They don't need a different name. You're storing a copy of it in the vector, so you can reuse the same object to add each element into the vector – NathanOliver May 26 '20 at 16:52

1 Answers1

4

There is no reason to name the Person struct in the loop at all. You can simply push_back a Person onto the vector:

while( inStream.peek() != EOF )
{
    inStream >> nameInput >> num1 >> num2 >> num3; //read in data to variables

    vecPerson.push_back(Person{nameInput, {num1,num2,num3}});
}  

This avoids naming the structs inside the loop, or using the index i at all.

Also, the condition of your loop is incorrect. You should simply do:

while(inStream >> nameInput >> num1 >> num2 >> num3) //read in data to variables
    vecPerson.push_back(Person{nameInput, {num1,num2,num3}});

Now each Person in the vector has a "different name" by virtue of being able to index a Person at a particular position.

cigien
  • 50,328
  • 7
  • 37
  • 78