Перегруженный конструктор, реализующий закрытые члены класса - PullRequest
1 голос
/ 04 апреля 2020

В этом коде у меня есть перегруженный конструктор Record::Record(string s), который читает строку, я пытаюсь создать поток строки из 's' и использовать getline (stringStream, line, ",") для чтения каждого элемента из строка с "," в качестве разделителя, затем присвойте каждому элементу соответствующую переменную объекта. Конечная цель этого назначения - открыть файл, прочитать его данные, назначить данные соответствующим образом в векторе, затем записать и проанализировать данные в новый файл.

Мое понимание работы с частными учениками ограничено. Я не уверен, как go о написании конструктора. В прошлом я использовал указатель для закрытых членов (например, 'this-> foo;), на данный момент мне просто нужно понять, как реализовать содержимое Record, пока то, что я пробовал, было неверным, и я я могу только найти ссылки на использование указателей на int.

Обычно я бы go пошел в свою компьютерную лабораторию и попросил бы TA, но в настоящее время он близок из-за COVID.

Вот код для моих конструкторов и перегруженных операторов.

Запись. 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;

    }

Запись. ч

#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;
}

1 Ответ

1 голос
/ 04 апреля 2020

Вы можете сделать что-то вроде:

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));
}

Я предполагаю, что вы имеете в виду, что каждый параметр разделен ',', а не каждой строкой, если это не так, скажите что-нибудь.

Редактировать

Итак, в вашей основной функции есть пара проблем, а именно, цикл while getline, вероятно, будет иметь доступ out_of_range, вы можете использовать на основе диапазона for l oop, что позволяет избежать переполнения контейнера:

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);
}

Файл ofstream не открывается и не проверяется должным образом, вы можете сделать что-то вроде:

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;
}

Эта строка:

path == "";

Я уверен, что вы имели в виду:

path = "";

Рабочий образец

Один последнее замечание, using namespace std не очень хорошая практика .

...