0

The file has

CompanyNo, Items baught (3 from every company), totalpaid, totalreturn(due to bad product), relation with other company(if any(companyNo))

a787, apple, banana, strawberry, "32,888.00", "0.0" k798, g456
f238, "Orange, Juice", Kiwi, "20,666.03", 0.0
g456, "Fresh, Beef", Lamb, Chicken, "40,500.00", "4,134.00", f238

and so on I am trying to read it into a class

class Company {

    std::string CompanyNo;
    std::string Item1;
    std::string Item2;
    std::string Item3;
    double Paid;
    double Return;
    vector<std::string> RelatedTo;

public:

    Company(std::string CompanyNo, std::string Item1, std::string Item2, std::string Item3, double paid, double Return, std::vector<std::string> RelatedTo)
    {
        this->CompanyNo = CompanyNo;
        this->Item1 = Item1;
        this->Item2 = Item2;
        this->Item3 = Item3;
        this->Paid = Paid;
        this->Return = Return;
        this->RelatedTo = RelatedTo;
    };

    ~Client() {};

    Company(const Company& cn) {
        this->CompanyNo = cn.CompanyNo;
        this->Item1 = cn.Item1;
        this->Item2 = cn.Item2;
        this->Item3 = cn.Item3;
        this->Paid = cn.Paid;
        this->Return = cn.Return;
        this->RelatedTo = cn.RelatedTo;
    };

    Company() {};

    Company operator= (Company cn) {
        this->CompanyNo = cn.CompanyNo;
        this->Item1 = cn.Item1;
        this->Item2 = cn.Item2;
        this->Item3 = cn.Item3;
        this->Paid = cn.Paid;
        this->Return = cn.Return;
        this->RelatedTo = cn.RelatedTo;
        return cn;
    }

    void setCompanyNo(std::string i) { CompanyNo = i; };
    void setItem1(std::string i1) { Item1 = i1; };
    void setItem2(std::string i2) { Item2 = i2; };
    void setItem3(std::string i3) { Item3 = i3; };
    void setPaid(double p) {Paid = p; };
    void setReturn(double r) { Return = r; };
    void setRelatedTo(std::vector<std::string> rt) { RelatedTo = rt; }


    std::string getCompanyNo() const { return CompanyNo; }
    std::string getItem1() const { return Item1; }
    std::string getItem2() const { return Item2; }
    std::string getItem3() const { return Item3; }
    double getPaid() const { return Paid; }
    double getReturn() const { return Return; }
    vector<std::string> getRelatedTo() const { return RelatedTo; }

};

At the bottom is what I have tried but doesn't really store each value into the class. This is my first time reading complicated file with different number of columns and commas between strings and doubles like "32,888.00" should store like 32888.00 in class and through file is comma delimited items like "orange, juice" should store like orange, juice rather then orange and juice separately. And relation to other should store as vector since company can have relation with many companies or non. Any help would be appreciated thank you

vector <Company> Info;

Company parseLine(string str)
{
    vector<string> store;
    string tok;
    stringstream evaluator;
    Company retv;

    evaluator << str;
    {
        char double_quote_remover;
        evaluator >> double_quote_remover; 
        getline(evaluator, tok, '"'); 
        char comma_remover;
        evaluator >> comma_remover; 
    }

    char ch;

    while (evaluator >> ch && ch != ','); 

    tok = ""; 
    ch = ' '; 

    while (evaluator >> ch) {  
        if (isalpha(ch)) { evaluator.putback(ch); ch = ','; } 
        if (ch == '\"') getline(evaluator, tok, '\"'); 
        else if (ch == ',') getline(evaluator, tok, ','); 
            store.push_back(tok);
        tok = ""; 
    }

    retv.setRelatedTo(store); 

    return retv; 

}

bool readFile()
{
    std::ifstream myFile("Data.txt");
    if (!myFile.is_open())
    {
        cout << "FAILED" << "\n";
        return false;
    }
    string str;

    getline(myFile, str); 

    int i = 0;
    while (std::getline(myFile, str))
    {
        Company Company = parseLine(str);
        Info.push_back(Company);
    }
    return true;
}

int main()
{
    bool data = readFile();

}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • 1
    You can use `std::stringstream` as shown [here](https://stackoverflow.com/questions/11719538/how-to-use-stringstream-to-separate-comma-separated-strings). – Aditya Singh Rathore Apr 13 '21 at 06:13
  • 3
    See the [quoted](https://en.cppreference.com/w/cpp/io/manip/quoted) manipulator. – zdf Apr 13 '21 at 06:26

1 Answers1

1

It is me again!

I believe it would be easier if you just made a function that writes structured files and reads them:

#include <vector>
#include <sstream>
class Company {

    std::string CompanyNo;
    std::string Item1;
    std::string Item2;
    std::string Item3;
    double Paid;
    double Return;
    std::vector<std::string> RelatedTo;

public:

    Company(std::string CompanyNo, std::string Item1, std::string Item2, std::string Item3, double paid, double Return, std::vector<std::string> RelatedTo)
    {
        this->CompanyNo = CompanyNo;
        this->Item1 = Item1;
        this->Item2 = Item2;
        this->Item3 = Item3;
        this->Paid = paid; //there was an error here ;) you had capitalized the P in paid so it was setting itself to itself.
        this->Return = Return;
        this->RelatedTo = RelatedTo;
    };

    ~Company() {};

    Company(const Company& cn) {
        this->CompanyNo = cn.CompanyNo;
        this->Item1 = cn.Item1;
        this->Item2 = cn.Item2;
        this->Item3 = cn.Item3;
        this->Paid = cn.Paid;
        this->Return = cn.Return;
        this->RelatedTo = cn.RelatedTo;
    };

    Company() {};

    Company operator= (Company cn) {
        this->CompanyNo = cn.CompanyNo;
        this->Item1 = cn.Item1;
        this->Item2 = cn.Item2;
        this->Item3 = cn.Item3;
        this->Paid = cn.Paid;
        this->Return = cn.Return;
        this->RelatedTo = cn.RelatedTo;
        return cn;
    }

    void setCompanyNo(std::string i) { CompanyNo = i; };
    void setItem1(std::string i1) { Item1 = i1; };
    void setItem2(std::string i2) { Item2 = i2; };
    void setItem3(std::string i3) { Item3 = i3; };
    void setPaid(double p) { Paid = p; };
    void setReturn(double r) { Return = r; };
    void setRelatedTo(std::vector<std::string> rt) { RelatedTo = rt; }


    std::string getCompanyNo() const { return CompanyNo; }
    std::string getItem1() const { return Item1; }
    std::string getItem2() const { return Item2; }
    std::string getItem3() const { return Item3; }
    double getPaid() const { return Paid; }
    double getReturn() const { return Return; }
    std::vector<std::string> getRelatedTo() const { return RelatedTo; }

};


std::string WriteStructured(Company& c) {
    std::string str;
    str += '(' + c.getCompanyNo() + "):";
    str += '{' + c.getItem1() + ',' + c.getItem2() + ',' + c.getItem3() + '}';
    str += '['+std::to_string(c.getPaid())+','+std::to_string(c.getReturn())+ ']';
    str += '<';
    for (int i = 0; i < c.getRelatedTo().size(); ++i) {
        str += c.getRelatedTo()[i] + ',';
    }
    str += '>';
    return str;
}

Company ReadStructured(std::string str) {
    std::stringstream evaluator;
    Company c;
    char curr;
    std::string temp;

    evaluator << str;

    while(evaluator >> curr&&curr!='(');

    getline(evaluator, temp, ')');
    c.setCompanyNo(temp);

    while (evaluator >> curr && curr != ':');
    while (evaluator >> curr && curr != '{');

    getline(evaluator, temp, ',');
    c.setItem1(temp);
    getline(evaluator, temp, ',');
    c.setItem2(temp);
    getline(evaluator, temp, '}');
    c.setItem3(temp);

    while (evaluator >> curr && curr != '[');

    {
        double d;
        std::stringstream converter;
        getline(evaluator, temp, ',');
        converter << temp;
        converter >> d;
        c.setPaid(d);
        getline(evaluator, temp, ']');
        converter << temp;
        converter >> d;
        c.setReturn(d);
    }

    while (evaluator >> curr && curr != '<');

    {
        std::vector<std::string> Related;
        while (getline(evaluator, temp, ',')) {
            Related.push_back(temp);
        }
        c.setRelatedTo(Related);
    }

    while (evaluator >> curr && curr != '>');

    return c;
}

WriteStructured() takes a Company and outputs a structured version, and ReadStructured() takes a line and turns it into a company.

Note: There was an error in one of your constructors, I marked it with a comment.

Example of how to use the functions:

#include <fstream>
int main() {
    std::ifstream Input("Infile.txt");
    std::ofstream Output("Outfile.txt");
    std::string line;

    std::vector<Company> Companies; //vector of companies

    while (getline(Input, line)) //while we can still read lines
        Companies.push_back(ReadStructured(line)); //parse the lines and put them into our vector

    std::vector<std::string> Related = { "tyu9","5xyz" }; //example Related Vector
    Company c2("abc1", "Item1", "Item2", "Item3", 108.79, 3.47, Related); //example company

    line = WriteStructured(c2); //example of writing to a line, then
    Output << line; //outputting the line
}
  • thank you for the detailed answer, what should be in my main just reading the file into vector pointing to company Class? thank you – ibrahimovich Apr 14 '21 at 01:27
  • Hi! See the example I added –  Apr 14 '21 at 02:28
  • thank you for the quick response though the numbers in file contains comma like 3,888.00, the comma wouldn't allow it to be double? Thank you – ibrahimovich Apr 14 '21 at 06:02
  • @ibrahimovich Yes, C++ iostreams don't understand that a comma in 3,800.00 means thousand. They only understand 3800.00. You could make a class that understands them, though, and has iostreams that interpret it into something C++ can understand. If you ask a question on how to do it, I would be happy to assist. –  Apr 14 '21 at 15:44