[英]How to process txt with comma delimiter that also has comma as the thousands separator?
[英]How to extract string with comma delimiter from txt file and parse every element separete by comma delimiter into a class constructor
來源:文本文件存儲帳戶信息列表。 例如:
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 文件中提取帶逗號分隔符的字符串並將逗號分隔符分隔的每個元素解析為 class 構造函數?
我嘗試使用 stringstream 從每一行中提取數據。 但它不起作用。 我得到的 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() {};
};
測試代碼是這樣的:
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;
}
解析 CSV 文件是個老話題了。 您將在 stackoverflow 上找到至少 100 個帶有代碼示例的答案。 通常,您會找到 function std::getline
的解決方案。 請閱讀此處的文檔。 它可以從std::ifstream
中讀取字符,直到或直到一個分隔符(在我們的例子中是一個逗號) ,
然后將結果(不帶逗號)存儲在一個字符串中,並丟棄 stream 中的逗號。所以,把它扔掉. 這些字符將存儲在std::string
中。 如果需要數字或其他類型,我們需要使用適當的 function 將字符串轉換為其他類型。
示例:我們有一個由字符“1”、“2”和“3”組成的字符串,因此,“123”。 引號表示字符串類型。 如果我們想將此字符串轉換為 integer,我們可以使用 function std::stoi
。
在您的情況下,您有 2 個雙精度值。 因此,我們會將文件的輸入拆分為字符串,然后使用 function std::stod
將其中包含雙精度值的 2 個字符串進行轉換。
您還需要知道的是,通常使用兩步法。 這樣做是為了防止從一個 csv 行中提取所有字符串部分而引起的潛在問題。 所以,
std::istringstream
,最后 那么,rest就簡單了。 只需使用std::getline
來獲取您需要的數據。
最后但同樣重要的是,要讀取文件,我們只需打開它,逐行讀取,創建一個“EmployeeAccount”並將其推送到std::vector
最后我們做了一些調試 output。
請參閱以下可能的實施建議之一:
#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.