简体   繁体   English

如何从 txt 文件中提取带逗号分隔符的字符串,并将逗号分隔符分隔的每个元素解析为 class 构造函数

[英]How to extract string with comma delimiter from txt file and parse every element separete by comma delimiter into a class constructor

Source: text file stores list of account info.来源:文本文件存储帐户信息列表。 eg:例如:

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?如何从 txt 文件中提取带逗号分隔符的字符串并将逗号分隔符分隔的每个元素解析为 class 构造函数?

I have try to use stringstream to extract data from every line.我尝试使用 stringstream 从每一行中提取数据。 But it does not work.但它不起作用。 The EmployeeAccount class I got is down below:我得到的 EmployeeAccount class 在下面:

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

Parsing CSV file is an old topic.解析 CSV 文件是个老话题了。 You will find at least 100 answers with code examples here on stackoverflow.您将在 stackoverflow 上找到至少 100 个带有代码示例的答案。 Very often you will find a solution with the function std::getline .通常,您会找到 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.它可以从std::ifstream中读取字符,直到或直到一个分隔符(在我们的例子中是一个逗号) ,然后将结果(不带逗号)存储在一个字符串中,并丢弃 stream 中的逗号。所以,把它扔掉. The characters will be stored in a std::string .这些字符将存储在std::string中。 If numbers or other types are needed, we need to convert the string to the other type, using the appropriate function.如果需要数字或其他类型,我们需要使用适当的 function 将字符串转换为其他类型。

Example: We have a string consisting of characters '1', '2' and '3', so, “123”.示例:我们有一个由字符“1”、“2”和“3”组成的字符串,因此,“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 .如果我们想将此字符串转换为 integer,我们可以使用 function std::stoi

In your case, you have 2 double values.在您的情况下,您有 2 个双精度值。 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 .因此,我们会将文件的输入拆分为字符串,然后使用 function std::stod将其中包含双精度值的 2 个字符串进行转换。

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.这样做是为了防止从一个 csv 行中提取所有字符串部分而引起的潜在问题。 So,所以,

  • we first read a complete line,我们首先阅读完整的一行,
  • then put that line into a std::istringstream , and finally然后将该行放入std::istringstream ,最后
  • read input and split the CSV from there.读取输入并从那里拆分 CSV。

Then, the rest is simple.那么,rest就简单了。 Just use std::getline to al the data that you need.只需使用std::getline来获取您需要的数据。

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最后但同样重要的是,要读取文件,我们只需打开它,逐行读取,创建一个“EmployeeAccount”并将其推送到std::vector

At the end we do some debug output.最后我们做了一些调试 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";
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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