b3orion
b3orion

Reputation: 77

Reading in a .txt file word by word to a struct in C++

I am having some trouble with my lab assignment for my CMPT class... I am trying to read a text file that has two words and a string of numbers per line, and the file can be as long as anyone makes it.

An example is

Xiao Wang 135798642
Lucie Chan 122344566
Rich Morlan 123456789
Amir Khan 975312468
Pierre Guertin 533665789
Marie Tye 987654321

I have to make each line a separate "student", so I was thinking of using struct to do so, but I don't know how to do that as I need the first, last, and ID number to be separate.

struct Student{
    string firstName;
    string secondName;
    string idNumber;
};

All of the tries done to read in each word separately have failed (ended up reading the whole line instead) and I am getting mildly frustrated.

With the help from @Sylence I have managed to read in each line separately. I am still confused with how to split the lines by the whitespace though. Is there a split function in ifstream? Sylence, is 'parts' going to be an array? I saw you had indexes in []'s. What exactly does the students.add( stud ) do? My code so far is:

int getFileInfo()
{
    Student stdnt;
    ifstream stdntFile;
    string fileName;
    char buffer[256];
    cout<<"Please enter the filename of the file";
    cin>>filename;
    stdntFile.open(fileName.c_str());
    while(!stdFile.eof())
    {
        stdFile.getLine(buffer,100);
    }
    return 0;
}

This is my modified and final version of getFileInfo(), thank you Shahbaz, for the easy and quick way to read in the data.

void getFileInfo()
{
    int failed=0;
    ifstream fin;
    string fileName;
    vector<Student> students; // A place to store the list of students

Student s;                  // A place to store data of one student
cout<<"Please enter the filename of the student grades (ex. filename_1.txt)."<<endl;
do{
    if(failed>=1)
        cout<<"Please enter a correct filename."<<endl;
    cin>>fileName;
fin.open(fileName.c_str());// Open the file
failed++;
}while(!fin.good());
while (fin >> s.firstName >> s.lastName >> s.stdNumber)
    students.push_back(s);
fin.close();
cout<<students.max_size()<<endl<< students.size()<<endl<<students.capacity()<<endl;


return;
}

What I am confused about now is how to access the data that was inputted! I know it was put into a vector, but How to I go about accessing the individual spaces in the vector, and how exactly is the inputted data stored in the vector? If I try to cout a spot of the vector, I get an error because Visual Studio doesn't know what to output I guess..

Upvotes: 2

Views: 3921

Answers (3)

Shahbaz
Shahbaz

Reputation: 47523

The other answers are good, but they look a bit complicated. You can do it simply by:

vector<Student> students;   // A place to store the list of students

Student s;                  // A place to store data of one student

ifstream fin("filename");   // Open the file

while (fin >> s.firstName >> s.secondName >> s.idNumber)
    students.push_back(s);

Note that if istream fails, such as when the file finishes, the istream object (fin) will evaluate to false. Therefore while (fin >> ....) will stop when the file finishes.

P.S. Don't forget to check if the file is opened or not.

Upvotes: 2

Loki Astari
Loki Astari

Reputation: 264411

Define a stream reader for student:

std::istream& operator>>(std::istream& stream, Student& data)
{
    std::string line;
    std::getline(stream, line);

    std::stringstream   linestream(line);
    linestream >> data.firstName >> data.secondName >> data.idNumber;

    return stream;
}

Now you should be able to stream objects from any stream, including a file:

int main()
{
    std::ifstream    file("data");
    Student          student1;

    file >> student1;   // Read 1 student;

    // Or Copy a file of students into a vector
    std::vector<Student>   studentVector;
    std::copy(std::istream_iterator<Student>(file),
              std::istream_iterator<Student>(),
              std::back_inserter(studentVector)
             );
}

Upvotes: 1

Sylence
Sylence

Reputation: 3073

Simply read a whole line and then split the string at the spaces and assign the values to an object of the struct.

pseudo code:

while( !eof )
   line = readline()
   parts = line.split( ' ' )

   Student stud = new Student()
   stud.firstName = parts[0]
   stud.secondName = parts[1]
   stud.idNumber = parts[2]  

   students.add( stud )     
end while

Upvotes: 0

Related Questions