简体   繁体   中英

Can't read file and store in data members of struct

This is for an assignment so I'm following assignment guidelines of the desired struct layout as well as the overloads. Trying to get my program to read each line and assign each line to the variable.

The text file looks like:

John 

S

Maggey

G

and my code looks like:

#include "iostream"
#include "fstream"
namespace
{
    char buffer[1024];
    int allocated = 0;
}

//====================================================================
struct student
{
    char *firstname;
    char lastname;
    int studentId;
    int occupied;

    student() : lastname(0), studentId(0), occupied(0)
    {
        firstname = new char[64];
        for (int i = 0; i < 64; ++i)
            firstname[i] = 0;
    }

    student(int s)
    {
        std::cout << "constructor" << std::endl;
        std::cout << "Allocated: " << allocated << std::endl;
        int currentLoc = allocated;
        allocated += s;
        firstname = new (&buffer[currentLoc]) char[s];
        for (int i = 0; i < 64; ++i)
            firstname[i] = 0;
    }

    void *operator new(size_t s)
    {
        std::cout << "Operator new allocated: " << allocated << std::endl;
        int currentLoc = allocated;
        allocated += s;
        return &buffer[currentLoc];
    }

    void student::operator delete(void *ptr)
    {
        std::cout << "Delete called " << std::endl;
        std::free(ptr);
    }

    student::~student()
    {
    }
};

//====================================================================
int main(int argc, char** argv)
{
    student *studentLoader = new student[25];

    std::fstream fin;
    fin.open("students.txt");
    char ln;
    for (int i = 0; i < 25; ++i)
    {
        fin.getline(studentLoader[i].firstname, 99);
        fin.getline(ln, 64);
        studentLoader[i].lastname = ln;
        studentLoader[i].studentId = (rand() % (9999 - 999)) + 999;
        studentLoader[i].occupied = 1;
        if ((i % 10) == 0)
        {
            std::cout << "First name: " << studentLoader[i].firstname << " Last initial: " << studentLoader[i].lastname << " ID: " << studentLoader[i].studentId << std::endl;
            delete[] studentLoader;
        }
    }
    fin.close();

    return 0;
}

I also tried doing :

    std::fstream fin;
    fin.open("students.txt");
    char ln;
    for (int i = 0; i < 25; ++i)
    {
        fin.getline(studentLoader[i].firstname, 99);
        fin.getline(studentLoader[i].lastname, 99);
        studentLoader[i].lastname = ln;
        studentLoader[i].studentId = (rand() % (9999 - 999)) + 999;
        studentLoader[i].occupied = 1;
        if ((i % 10) == 0)
        {
            std::cout << "First name: " << studentLoader[i].firstname << " Last initial: " << studentLoader[i].lastname << " ID: " << studentLoader[i].studentId << std::endl;
            delete[] studentLoader;
        }
    }
    fin.close();

    return 0;
}

But would receive an error for the second attempt to getline.

When trying

fin >> studentLoader[i].firstname;

nothing would be inserted into the variables.

If this is not a typo and you really wanted to use single character for the lastname you should read it as a single character as well: fin >> studentLoader[i].lastname >> std::ws .

Also consider reading documentation for the functions and classes you are using. This is generally good habit and will save you from fair amount of failures.

By slightly modifying you struct student by changing the type of firstname and lastname to std::string , you won't have to dynamically allocate / deallocate memory and you will reduce the code by half.

For example, you could define it as:

struct student {

    // constructor
    student (std::stirng fn, std::stirng ln, int ID, int oc) 
       :  firstname(fn), lastname(ln), studentID(ID), occupied(oc) { }

    // data members
    std::string firstname;
    std::string lastname;  
    int studentID;
    int occupied;
}; 

then to read from file and store in struct student , you could use std::vector , like so:

#include <iostream>
#include <string>
#include <vector>
#include <sstream> 

int main () {
    // stores all elements created from the reading of the file 
    std::vector<student> class_of_students;

    // attach an input stream
    std::ifstream fin("students.txt");
    // check if file successfully opened 
    if (!fin) std::cerr << "Can't open input file!\n";

    // line of text
    std::string line;

    // read file line by line
    while (getline(fin, line)) {
         // stream to extract data from a line
         std::stringstream ss(line);

         // input variables
         std::string first_name;
         std::string last_name;
         int ID;
         int occupied;

         // example that assumes line format: "f_name l_name ID occ"
         while (ss >> first_name >> last_name >> ID >> occupied) {

             // store one element of type student to the vector
             class_of_students.emplace_back(student(first_name, last_name, ID, occupied));
         }
    }
}

More on the use of std::string and std::vector .

Note:

In addition, when you generate a student ID you need it to be not only random, but also unique.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM