0

the text file looks something like this:

9528961 Adney Smith CS 4.2
9420104 Annalynn Jones EE 2.6
9650459 Bernadette Williams IT 3.6
...

there are 45 lines in the text file meaning 45 students. I have read the text file and when I run the program I get this:

9428167
Mason
Taylor
CS
4.8
9231599
Alexander
Jones
CS
2.3

My main file looks like this:

int main()
{
    auto student = new Student<string>();
    std::vector<string> students;
    std::ifstream inputFile;
    inputFile.open("enroll_assg.txt");
    std::string line;
    if(inputFile.is_open()){
        while(std::getline(inputFile, line)){
                std::istringstream iss(line);
                std::string word;
                while(iss >> word){
                    std::cout << word << std::endl;
                    for(int i = 0; i < 5; i++){
                        

                    }
                }
        }
    } 
    return 0;
}

Each student has 5 columns (id, fname, lname, department, gpa) and I need make a vector which includes all these student object. I need some help doing this so comments and answers are most welcome. Thank you.

  • Side note: Use `new` sparingly. Every time you use `new` the computer has to do a lot more work to get storage AND you-the-programmer have to go through the hell of making sure the object gets put back correctly by calling `delete` at thew right place and time and only once. Sounds simple, `new blah` *use blah*, `delete blah;` and it is up until *use blah* is spread over a few hundred or a few thousand lines of multithreaded code. – user4581301 Dec 02 '21 at 23:42
  • If you `Student student;`, the memory allocation is (typically) moving the stack pointer and you don't have to worry about `delete student;` because the program does it for you as soon as the program reaches the end of the block of code it was defined in. You just have to make sure that block of code lasts longer than everything using `student`. – user4581301 Dec 02 '21 at 23:42
  • 2
    Duplicate of [Read lines from text file and store into array](https://stackoverflow.com/questions/70149932/read-lines-from-text-file-and-store-into-array) by the same OP. – Jason Dec 03 '21 at 04:40

3 Answers3

2

Try something more like this instead:

int main()
{
    std::ifstream inputFile("enroll_assg.txt");
    if (inputFile.is_open()){
        std::vector<Student<string>> students;
        std::string line;
        while (std::getline(inputFile, line)){
            std::istringstream iss(line);
            Student<string> student;
            iss >> student.id;
            iss >> student.fname;
            iss >> student.lname;
            iss >> student.department;
            iss >> student.gpa;
            students.push_back(student);
        }
        // use students as needed...
    }
    return 0;
}

Then, you should consider having Student overload the operator>>, which will greatly simplify the loop so you can do something more like this instead:

template<typename T>
std::ostream& operator>>(std::ostream &in, Student<T> &student)
{
    std::string line;
    if (std::getline(in, line))
    {
        std::istringstream iss(line);
        iss >> student.id;
        iss >> student.fname;
        iss >> student.lname;
        iss >> student.department;
        iss >> student.gpa;
    }
    return in;
}

int main()
{
    std::ifstream inputFile("enroll_assg.txt");
    if (inputFile.is_open()){
        std::vector<Student<string>> students;
        Student<string> student;
        while (inputFile >> student){
            students.push_back(student);
        }
        // use students as needed...
    }
    return 0;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • it is giving me an error at std::vecotr students saying its argument list is missing. – codingisfun543 Dec 03 '21 at 02:08
  • Obviously, this is contingent on you having a `Student` class defined. In your original code, you have `auto student = new Student();`. Why is `Student` templated? In any case, I have updated my example to use `Student` instead of `Student`. – Remy Lebeau Dec 03 '21 at 03:16
  • @codingisfun543 Why are you spamming by asking duplicate questions? You already have an answer to your question at [here](https://stackoverflow.com/questions/70149932/read-lines-from-text-file-and-store-into-array) –  Dec 03 '21 at 04:45
1

IMHO, the best method is to use a struct or class to model or represent the data record you need to read.

struct Student
{
    unsigned int id;
    std::string  first_name;
    std::string  last_name;
    std::string  major_code;
    double       gpa;
    friend std::istream& operator>>(std::istream& input, Student& s);
};

std::istream& operator>>(std::istream& input, Student& s)
{
    input >> s.id;
    input >> s.first_name;
    input >> s.last_name;
    input >> s.major_code;
    input >> s.gpa;
    input.ignore(10000, '\n'); // Synchronize to next line.
    return input;
}

Your input code could look like this:

std::vector<Student> database;
Student s;
//... open file.
while (student_file >> s)
{
    database.push_back(s);
}

The above code will read each student record into a database, so you can analyze it.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
  • Small nitpick: When your `operator>>` is calling `input.ignore()`, you should use `std::numeric_limits::max()` instead of a hard-coded limit like `10000`. `ignore()` has special handling of this `max()` value to truly read *infinitely* until the delimiter is found or eof/error is encountered. Using any other numeric value doesn't offer that same guarantee. – Remy Lebeau Dec 02 '21 at 23:35
  • That said, if the program has to read more than a few thousand characters to find the end of a line, something has gone very, very wrong and you might want to stop and check out what. Which route you take to recover from an error depends on the requirements of the program. Just make sure you do recover from the error or exit the program as safely as you can if the error can't be handled. – user4581301 Dec 02 '21 at 23:47
0

First this question is a duplicate of Read lines from text file and store into array which already has the answer you're looking for in this question.

The below shown program uses struct to represent a given Student and it also used a std::vector. You can use this program as a reference(starting point). It reads student information from the input text file and store that information in a vector of Student.

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
//this class represents a Student
class Student
{
    public:
        std::string firstName, lastName, courseName ;
        unsigned long id = 0;
        float marks = 0;
    
};

int main()
{
   std::ifstream inputFile("input.txt");
   std::string line;
   std::vector<Student> myVec;//create a vector of Student objects
   if(inputFile)
   {
       while(std::getline(inputFile, line))
       {
           Student studentObject;
           std::istringstream ss(line);
           //read the id 
           ss >> studentObject.id;
           
           //read the firstname 
           ss >> studentObject.firstName;
           
           //read the lastname 
           ss >> studentObject.lastName;
           
           //read the courseName
           ss >> studentObject.courseName;
           
           //read the marks 
           ss >> studentObject.marks; 
           
           if(ss)//check if input succeded
           {
               myVec.emplace_back(studentObject);//add the studentObject into the vector
           }
       }
   }
   else 
   {
       std::cout<<"File cannot be opened"<<std::endl;
   }
   
   //lets print out the elements of the vecotr to confirm that all the students were correctly read 
   for(const Student &elem: myVec)
   {
       std::cout << elem.id << ": "<<elem.firstName<<" "<<elem.lastName<<" "<<elem.courseName<<" "<<elem.marks <<std::endl;
   }
    return 0;
}

The output of the above program can be seen here.

Jason
  • 36,170
  • 5
  • 26
  • 60