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

发布于 2025-01-17 04:28:20 字数 3025 浏览 2 评论 0原文

来源:文本文件存储帐户信息列表。例如:

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,
....
....
....

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

我尝试使用 stringstream 从每一行中提取数据。但这不起作用。 我得到的 EmployeeAccount 类如下:

#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() {};
};

测试代码是这样的:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

大姐,你呐 2025-01-24 04:28:21

解析 CSV 文件是一个老话题了。您将在 stackoverflow 上找到至少 100 个带有代码示例的答案。通常,您会通过函数 std::getline 找到解决方案。请阅读此处的文档。它可以从 std::ifstream 读取字符,直到达到分隔符(在我们的例子中为逗号 ,),然后将结果(不带逗号)存储在字符串并丢弃流中的逗号。所以,把它扔掉。这些字符将存储在 std::string 中。如果需要数字或其他类型,我们需要使用适当的函数将字符串转换为其他类型。

示例:我们有一个由字符“1”、“2”和“3”组成的字符串,即“123”。引号表示字符串类型。如果我们想将此字符串转换为整数,我们可以使用例如函数 std::stoi

就您而言,您有 2 个双精度值。因此,我们将文件的输入拆分为字符串,然后使用函数 std::stod 转换其中包含双精度值的 2 个字符串。

您还需要了解的是,通常使用两步方法。这样做是为了防止从一个 csv 行中提取所有字符串部分而引起的潜在问题。因此,

  • 我们首先读取完整的行,
  • 然后将该行放入 std::istringstream 中,最后
  • 读取输入并从那里拆分 CSV。

然后,剩下的就简单了。只需使用 std::getline 即可获取您需要的数据。

最后但并非最不重要的一点是,要读取该文件,我们只需打开它,逐行读取,创建一个“EmployeeAccount”并将其推送到 std::vector

最后,我们进行一些调试输出。

请参阅下面可能的潜在实施建议之一:

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文