Pulling info from a file and creating an object

Hello I am pretty new in regards to fstream and file manipulation. So I have a hw problem where I am reading a file with a list of <first name> <M or F> <frequency of name> and my job is to read line by line taking each bit of info and passing into an object. Then pass that object into a vector. I am having the problem of how do each piece of information from the file and save into the according variable within the object.

for example
taking the first name of the person and passing into a string variable called name.

Another example is taking the frequency and storing it into an int.

I would like some help spear heading my project because I generally don't know how to pull indivudal info and store it. I know how to store the entire file or line into a single vector but not multiple data types.
Last edited on
It can be as simple as the following, or it can be more object-oriented if you want (making data private, defining overloads for operator<< and operator>>, etc.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

struct Name
{
    string m_name;
    char   m_gender;
    int    m_freq;
};

vector<Name> read_names(const string& filename)
{
    vector<Name> names;
    ifstream in(filename);
    Name name;
    while (in >> name.m_name >> name.m_gender >> name.m_freq)
        names.push_back(name);
    return names;
}

void print_names(const vector<Name>& names)
{
    for (const Name& name: names)
        cout << name.m_name   << ' '
             << name.m_gender << ' '
             << name.m_freq   << '\n';
}

int main()
{
    vector<Name> names {read_names("names.txt")};
    print_names(names);
}

it has to be a bit more object-oriented ish.
this is the code I have been working with/ trying to work; however, it keeps iterating through the begin two while loops

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 while(!ioFile.eof()) {

    
    while (ioFile >> tempName >> tempGender >> tempFreq) {
      if (tempGender == "F") {
        girlVec[girlCounter].setGender(tempGender);
        while (ioFile >> tempName) {
          girlVec[girlCounter].setName(tempName);
          break;
        }
        while (ioFile >> tempFreq) {
          girlVec[girlCounter].setFreq(tempFreq);;
          break;
        }
        girlCounter++;
      } else {
        boyVec[boyCounter].setGender(tempGender);
        while (ioFile >> tempName) {
          boyVec[boyCounter].setName(tempName);
          break;
        }
        while (ioFile >> tempFreq) {
          boyVec[boyCounter].setFreq(tempFreq);;
          break;
        }
        boyCounter++;
      }
      break;

    }
  }


Also I cant use the struct in this project unfortunately so this is the class I have been working with
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class Person {
  private:
    int freq;
    string name;
    string gender;

  public: 
    Person() {
      freq = 0;
      name = " ";
      gender = " ";
    }

    //gettor function
    int getFreq() {
      return freq;
    }

    string getName() {
      return name;
    }

    string getGender() {
      return gender;
    }


    //settor functions
    void setFreq(int temp) {
      freq = temp;
    }

    void setName(string temp) {
      name = temp;
    }

    void setGender(string temp) {
      gender = temp;
    }
};

 
Last edited on
It looks like you might want something like this.

1
2
3
4
5
6
7
8
9
10
    while (ioFile >> tempName >> tempGender >> tempFreq) {
        Person person;
        person.setGender(tempGender);
        person.setName(tempName);
        person.setFreq(tempFreq);
        if (tempGender == "F")
            girlVec.push_back(person);
        else
            boyVec.push_back(person);
    }
Ok so I am a bit confused how does doing something like (ioFile >> tempName >> tempGender >> tempFreq) allow me to extract each data type that I need becaue when I throw it through a debugger it just ends without separating the first line of code into. instread it assigns the first two line of code two the two string varibles

something like this
tempName = <name of person>
tempGender = <M or F>
tempFreq = 48493

I don't understand what you're saying.
Last edited on
My Bad I am tired, I meant to say is this. When I run this line of code (ioFile >> tempName >> tempGender >> tempFreq) it does not separate what is being read from the file which is some thing like this "John, M, 487267". so I am just confused in general on how to separate something like this "John, M, 487267" in the following:

string tempName = John
char tempGender = M
int tempFreq = 487267

Thank you for helping me my teacher with this whole online learn he does not explain things well.

I am also trying a different method of separating the line of code, does something like this work better?

1
2
3
4
5
6
7
8
9
while (!ioFile.eof()) {
  getline(ioFile, read); //reads line by line
  test.push_back(read); //pushes the line into a string vector
  baby bf; //creates an object for the info to be stored
for (int i = 0; i < test.size(); i++) { //runs through entire line
    if (test[i] == "F") { //checking if the char at this position is Female or male
      bf.setGender(test[i]); // suppose to set a char to object
    }
  }

Last edited on
I didn't know about the commas. Maybe something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    string name, gender;
    int freq;

    while (getline(ioFile, name, ',')) {
        ioFile >> gender >> freq;
        gender.pop_back(); // remove comma from gender
        ioFile.ignore(999, '\n'); // eat newline
        Person person;
        person.setName(name);
        person.setGender(gender);
        person.setFreq(freq);
        if (gender == "F")
            girlVec.push_back(person);
        else
            boyVec.push_back(person);
    }

Last edited on
So this is what i have in my code right now. so it separated the name but leaves
"F, 84758" in the gender variable and skips over freq. since gender is a char could I do something like freq = atoi(gender) and then set the object's freq. However, i don't know how to get rid of everything past the F in the gender varible

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;

class Person {
  private:
    int freq;
    string name;
    string gender;

  public: 
    Person() {
      freq = 0;
      name = " ";
      gender = " ";
    }

    //gettor function
    int getFreq() {
      return freq;
    }

    string getName() {
      return name;
    }

    string getGender() {
      return gender;
    }


    //settor functions
    void setFreq(int temp) {
      freq = temp;
    }

    void setName(string temp) {
      name = temp;
    }

    void setGender(string temp) {
      gender = temp;
    }
};

int main() {
  string name, gender;
  int freq;

   vector <Person> boyVec;
  vector <Person> girlVec;

  ifstream ioFile;
  ioFile.open("yob2015.txt");
  if(!ioFile) {
    cout <<  "didn't open file!" << endl;
    return 1;
  }


  while(getline(ioFile, name, ',')) {
    char comma;
    ioFile >> gender >> comma >> freq;
    Person person;
    person.setName(name);
    person.setGender(gender);
    person.setFreq(freq);
    if (gender == "F") {
      girlVec.push_back(person);
    } else {
      boyVec.push_back(person);
    }
  }


Try this. Note that name, gender, freq can be removed form the top of main since they're inside the while now.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    string line;
    while (getline(ioFile, line)) {

        istringstream ss(line);    // #include <sstream>
        string name, gender;
        int freq;

        getline(ss, name, ',');
        ss >> ws; // skip whitespace (if any)
        getline(ss, gender, ',');
        ss >> freq;

        Person person;
        person.setName(name);
        person.setGender(gender);
        person.setFreq(freq);

        if (gender == "F")
            girlVec.push_back(person);
        else
            boyVec.push_back(person);
    }

Last edited on
Thank so much for coaching me though this.
You may wish to further re-factor the design and implementation of this code for several reasons – the main ones being code re-usability and conformance to the single responsibility principle (refer to DRY and SOLID principles).

Your task is to parse a text file containing data (stored in a pre-defined format) in order to construct an in-memory representation of this data (for further processing).

You could look at implementing further classes related to the parsing of the file to construct the in-memory representation of this data. This could be achieved simply by creating a PersonTextFileParser class.

A more advanced approach would be to implement an abstract base class (e.g., PersonFileParserI) to provide a common interface for classes which allow for the parsing of this data from files of different formats (e.g., PersonTextFileParser, PersonXmlFileParser, etc).

The same approach could then be applied for classes which generate an output file from the in-memory representation of the data.

But this requires some understanding of class inheritance, abstract interface classes, etc.
Topic archived. No new replies allowed.