简体   繁体   中英

Overloaded constructor implementing private class members

In this code I have an overloaded constructor Record::Record(string s) that reads in a string, I am trying to create a string stream from 's' and use getline(stringStream, line, ",") to read each element from the string with "," as the delimiter, then assign each element to the appropriate object variable. The end goal of this assignment is to open a file, read in its data, assign the data appropriately in a vector, then write and parse the data to a new file.

My understanding of working with private class members is limited. I am unsure how to go about writing the constructor. In the past I've used a pointer for private members (eg 'this-> foo;), at this point I just need to understand how to implement the contents of Record, so far what I've tried has been incorrect and I can only find references to using pointers to int's.

Normally I would go to my comp-sci lab and ask a TA but it is currently close due to COVID.

Here is the code for my constuctors and overloaded operators.

Record.cpp

    #include <string>
    #include <sstream>
    #include "Record.h"

    using namespace std;

    Record::Record(string s) {

  /**  here is where I need to assign data to the following.
                std::string department;
                std::string item_code;
                int quantity;
                double cost;  **/
    }

    Record::~Record() {
        // TODO Auto-generated destructor stub
    }

    //overloaded "==" and "<" comparison operators

    bool operator ==(const Record &lhs, const Record &rhs){
        return (lhs.cost == rhs.cost && lhs.department == rhs.department &&
                lhs.item_code == rhs.item_code && lhs.quantity == rhs.quantity);
    }

    /**bool operator <(const Record &a, const Record &b){ //do not need at this time

    }
    **/

    //Overloaded "<<" operator
    std::ostream& operator <<(std::ostream& os, const Record& r){
        os << r.department << ',' << r.item_code << ',' <<  r.quantity << ',' << r.cost;
        return os;

    }

Record.h

#ifndef RECORD_H_
#define RECORD_H_

#include <iostream>
#include <string>

class Record {
public:

    //Constructor
    Record(std::string s); //pass this string to our Record class

    //De-constructor
    virtual ~Record();

    //overloaded "==" and "<" comparison operators

    friend bool operator ==(const Record &a, const Record &b);

    //friend bool operator <(const Record &a, const Record &b);  //Do not need at this time.

    //Overloaded "<<" operator

    friend std::ostream& operator <<(std::ostream&, const Record&);


private:
        std::string department;
        std::string item_code;
        int quantity;
        double cost;

};

#endif /* RECORD_H_ */

Main.cpp

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <libgen.h>
#include <fstream>
#include <sstream>
#include <vector>
#include <algorithm>
#include "Record.h"
using namespace std;

int main() {

    vector<Record> records; //vector of type Records to hold each "Line" of input file
    string filename;        // File name and path stored as string

    /**
     * Prompts user for the name of input file and stores in string variable filename
     *
     */
    cout << "please enter the name of your file with file path:" << endl;
    cin >> filename;
    ifstream ifs { filename.c_str() };
    if (!ifs) {
        cerr << " Can't open file " << filename << endl;
        return 1;
    }

    string path = filename.substr(0, filename.find_last_of("\\/"));
    string file = filename.substr(filename.find_last_of("\\/") + 1,
            filename.length());
    if (path.compare(file) == 0) {
        path == "";
    }
    //test for file and file path

    cout << "Path portion of " << filename << " is " << path << endl;
    cout << "File portion of " << filename << " is " << file << endl; // path + "new_" + file + ".cvs", make new file with new path

    /**
     * Put each line of input file in to the records vector
     */

    string line; //strings for each parameter of the vector object


    while (getline(ifs, line)) {

        Record newRecord(line); //this should check for duplicates and ignore any found.
        int i = 0;
        int n = 0;
            if((newRecord == records[i]) || (i < n) ){
                i++;
            }
            else{
                records.push_back(newRecord);
                n++;
                i = 0;
            }
    }
    ifs.close(); //closes the stream

    //create new file and output data to it
    string newFile = ("new_" + file + ".cvs");

    //check to see if file path and file name are correct
    cout << (path + newFile);


    //Open stream to new file and write to it

    ofstream ofs(path + newFile);
    ofs.open(newFile);

    for(size_t i = 0; i < records.size(); i++){
        ofs << (i+1) << ' ' << records[i];
    }

    ofs.close(); //close output stream

    return 0;
}

You can do something like:

Record::Record(std::string s){

    std::string word;
    std::vector<std::string> temp;
    std::stringstream ss(s);

    while(getline(ss, word, ','))
        temp.push_back(word);

    department = temp.at(0);
    item_code =  temp.at(1);
    quantity = stoi(temp.at(2));
    cost = stod(temp.at(3));
}

I'm assuming you mean that each parmeter is separated by ',' , not each line, if that's not the case, say something.

Edit

So there are a couple of issues in your main function, namely, the while getline cycle will probably have out_of_range access, you can use a range-based for loop, which avoids container overflow:

while (getline(ifs, line))
{
    bool flag = 1;
    Record newRecord(line); 

    for(Record r : records){
        if(r == newRecord){
            flag = 0;
            break;
        }
    }
    if(flag)
        records.push_back(newRecord);
}

The ofstream file is not being properly opened and tested, you can do something like:

ofstream ofs;
ofs.open(path + newFile);

if (!ofs)
{
    cerr << "Can't open file " << filename << endl;
    return 1;
}

for (size_t i = 0; i < records.size(); i++)
{
    ofs << (i + 1) << ' ' << records[i] << endl;
}

This line:

path == "";

I'm sure you meant:

path = "";

Running sample

One last note, using namespace std is not a very good practice .

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