Home > Enterprise >  How to extract string with comma delimiter from txt file and parse every element separete by comma d
How to extract string with comma delimiter from txt file and parse every element separete by comma d

Time:03-30

Source: text file stores list of account info. e.g:

10041249,Mr,Vincent,Rogan,Rogan Locksmiths Ltd,Nell,5287.000000,,491.691000,
10021250,Mrs,Adele,Cunningham,Cunningham Demolition Ltd,Dr Scott,2941.000000,,273.513000,
10051251,Mr,Rodney,Shaw,Shaw Meat Packaging Ltd,Eddie,7552.000000,,740.096000,
10001252,Mrs,Christine,Nichols,Nichols Scaffolding Ltd,Brad,6723.000000,Eddie:Brad:,672.300000,
10021253,Mr,Alexander,Marshall,Marshall Chemicals Ltd,Dr Scott,1768.000000,,173.264000,
10021254,Ms,Shirley,Hagman,On Point Sportswear Ltd,Dr Scott,52.000000,,5.200000,
....
....
....

How to extract string with comma delimiter from txt file and parse every element separate by comma delimiter into a class constructor?

I have try to use stringstream to extract data from every line. But it does not work. The EmployeeAccount class I got is down below:

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

using namespace std;

class EmployeeAccount {
private:
    //member variable
    string acountNumber;
    string title; 
    string firstname; 
    string lastname; 
    string company; 
    string salesperson; 
    double purchaseValue; 
    string prev_salestaff; 
    double commission; 

public:

    //overload constructor
    EmployeeAccount(const string& employeeAccountInfo)
    {
        string str;
        stringstream employeeAccountStream(employeeAccountInfo);
        while (getline(employeeAccountStream, str, ','))
        {
            stringstream sso(str); 
                sso >> acountNumber; 
                sso >> title; 
                sso >> firstname; 
                sso >> lastname; 
                sso >> company; 
                sso >> salesperson; 
                sso >> purchaseValue; 
                sso >> prev_salestaff; 
                sso >> commission; 
        }
    }
    //Access methods
    string getAccountNumber() { return acountNumber; }; 
    string getTitle() { return title; }; 
    string getFirstname() { return firstname; }; 
    string getLastname() { return lastname; }; 
    string getCompany() { return company; }; 
    double getPurchaseValue() { return purchaseValue; }; 
    string getPrev_salesstaff() { return prev_salestaff; }; 
    double getCommission() { return commission; }; 
    string getAccountDetail() { return acountNumber   " "   title   " "   firstname   " "   lastname   " "   company;};

    //Destructor
    ~EmployeeAccount() {};
};

The testing code is this:

    cout << testEmployee.getAccountDetail() << endl;
    cout << testEmployee.getAccountNumber() << endl;
    cout << testEmployee.getTitle() << endl;
    cout << testEmployee.getFirstname() << endl;
    cout << testEmployee.getLastname() << endl;
    cout << testEmployee.getCompany() << endl;
    cout << testEmployee.getPurchaseValue() << endl;
    cout << testEmployee.getPrev_salesstaff() << endl;
    cout << testEmployee.getCommission() << endl;
}

CodePudding user response:

Parsing CSV file is an old topic. You will find at least 100 answers with code examples here on stackoverflow. Very often you will find a solution with the function std::getline. Please read the documentation here. It can read characters from a std::ifstream until or up to a delimiter (a comma , in our case), then store the result, without the comma, in a string and discard the comma from the stream. So, throwing that away. The characters will be stored in a std::string. If numbers or other types are needed, we need to convert the string to the other type, using the appropriate function.

Example: We have a string consisting of characters ‘1’, ‘2’ and ‘3’, so, “123”. The quotes indicate the string type. If we want to convert this string into an integer, we can use for example the function std::stoi.

In your case, you have 2 double values. So, we would split the input of the file into strings and then convert the 2 strings with the double values in it, using the function std::stod.

What you need to know additionally is, that often a 2 step approach is used. This is done to prevent potential problems arising from extracting all the string parts from one csv line. So,

  • we first read a complete line,
  • then put that line into a std::istringstream, and finally
  • read input and split the CSV from there.

Then, the rest is simple. Just use std::getline to al the data that you need.

Last but not least, to read the file, we will simply open it, read line by line, create an “EmployeeAccount” and push that into a std::vector

At the end we do some debug output.

Please see below one of may potential implementation proposals:

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


class EmployeeAccount {
private:
    //member variable
    std::string acountNumber;
    std::string title;
    std::string firstname;
    std::string lastname;
    std::string company;
    std::string salesperson;
    double purchaseValue; 
    std::string prev_salestaff;
    double commission; 

public:

    //overload constructor
    EmployeeAccount(const std::string& employeeAccountInfo)
    {
        std::istringstream employeeAccountStream(employeeAccountInfo);
        std::getline(employeeAccountStream, acountNumber, ',');
        std::getline(employeeAccountStream, title, ',');
        std::getline(employeeAccountStream, firstname, ',');
        std::getline(employeeAccountStream, lastname, ',');
        std::getline(employeeAccountStream, company, ',');
        std::getline(employeeAccountStream, salesperson, ',');
        std::string temp;
        std::getline(employeeAccountStream, temp, ',');
        purchaseValue = std::stod(temp);
        std::getline(employeeAccountStream, prev_salestaff, ',');
        std::getline(employeeAccountStream, temp, ',');
        commission = std::stod(temp);
    }
    //Access methods
    std::string getAccountNumber() const { return acountNumber; };
    std::string getTitle()  const { return title; };
    std::string getFirstname()  const { return firstname; };
    std::string getLastname()  const { return lastname; };
    std::string getCompany()  const { return company; };
    double getPurchaseValue()  const { return purchaseValue; };
    std::string getPrev_salesstaff()  const { return prev_salestaff; };
    double getCommission()  const { return commission; };
    std::string getAccountDetail()  const { return acountNumber   " "   title   " "   firstname   " "   lastname   " "   company;};

    //Destructor
    ~EmployeeAccount() {};
};
int main() {
    std::ifstream ifs{ "accounts.txt" };
    if (ifs) {

        // Here we will store all accounts
        std::vector<EmployeeAccount> accounts{};

        // Read the file line by line
        std::string line{};
        while (std::getline(ifs, line)) {

            // Create one account by splitting the input line
            EmployeeAccount account(line);

            // Add the new accounts to the vector of accounts
            accounts.push_back(account);
        }

        // Debug output. For all accounts that we read, output all data
        for (const EmployeeAccount& account : accounts) {

            std::cout << "\n--------------------------\n"
             << account.getAccountDetail() << '\n'
             << account.getAccountNumber() << '\n'
             << account.getTitle() << '\n'
             << account.getFirstname() << '\n'
             << account.getLastname() << '\n'
             << account.getCompany() << '\n'
             << account.getPurchaseValue() << '\n'
             << account.getPrev_salesstaff() << '\n'
             << account.getCommission() << '\n';
        }
    }
    else
        std::cerr << "\n*** Error: Could not open source file\n\n";
}

  • Related