我有这样的数据;
InvoiceNo;StockCode;Description;Quantity;InvoiceDate;UnitPrice;CustomerID;Country
A;B;C;D;E;F;G;H
A2;B2;C2;D2;E2;F2;G2;H2
.
.
.
A500000;B500000;C500000;D500000;E500000;F500000;G500000;H500000
我正在使用该代码读取文件;
std::ifstream is("myData.csv", std::ifstream::binary);
if (is) {
is.seekg(0, is.end);
int length = is.tellg();
is.seekg(0, is.beg);
char* buffer = new char[length];
std::cout << "Reading " << length << " characters... ";
is.read(buffer, length);
if (is) {
std::cout << "all characters read successfully.";
}
else
std::cout << "error: only " << is.gcount() << " could be read";
is.close();
delete[] buffer;
}
我的问题是,如何将这些数据存储在链接列表中?我创建一个节点来存储StockCode,描述和数量。我如何从缓冲区获取该列数据?
我只能使用iostream,ctime,fstream,字符串库来解决该问题。没有向量。
首先,老师强迫人们在C ++中使用原始指针和C-Style数组,这是很可耻的。并且,为std::list
重新发明轮子。
我什至不能在给定包含列表下使用std::unique_ptr
。所以,主请谅解我:
#include <iostream> #include <fstream> #include <string> constexpr size_t NumberOfInvoiceDataEntries = 8; // Make reading easier // Lord forgive me for using plain C-Style arrays using InvoiceDataEntry = std::string[NumberOfInvoiceDataEntries]; // Split line into columns void splitLine(const std::string& csvLine, InvoiceDataEntry csvColumns) { // Initialize all needed value size_t columnIndex{ 0U }; size_t startPos{ 0U }; size_t i = 0U; // Iterate over all characters in the string do { // If we found semicolon or end of string, then we copy the sub-string if (csvLine[i] == ';' || i == csvLine.size()) { // Copy to column array. csvColumns[columnIndex++] = csvLine.substr(startPos, i - startPos);; startPos = i + 1; } ++i; } while (i <= csvLine.size()); } struct InvoiceData { // Our data InvoiceDataEntry data{}; // Overwrite inserter operator for easier input friend std::istream& operator >> (std::istream& is, InvoiceData& id) { if (std::string line{}; std::getline(is, line) && !line.empty()) { splitLine(line, id.data); } return is; } // Overwrite extractor operator for easier output friend std::ostream& operator << (std::ostream& os, const InvoiceData& id) { return os << "\nInvoice No: " << id.data[0] << "\nStock Code: " << id.data[1] << "\nDescription: " << id.data[2] << "\nQuantity: " << id.data[3] << "\nInvoice Date: " << id.data[4] << "\nUnit Price: " << id.data[5] << "\nCustomer ID: " << id.data[6] << "\nCountry: " << id.data[7] << "\n"; } }; struct LinkedListInvoiceData { // Destructor: clean up newed memory ~LinkedListInvoiceData() { delete next; } void add(const InvoiceData& id) { // Search end of linked list LinkedListInvoiceData* current = this; while (current->next != nullptr) current = current->next; // Assign new invoice data. current->invoiceData = id; current->next = new LinkedListInvoiceData(); } void print() { LinkedListInvoiceData* current = this; while (current != nullptr) { std::cout << current->invoiceData; current = current->next; } return; } private: LinkedListInvoiceData* next{ nullptr }; InvoiceData invoiceData{}; }; const std::string fileName("r:\\myData.csv"); int main() { // Open file and check if it is open if (std::ifstream ifs(fileName); ifs) { // The linked list with the invoice data LinkedListInvoiceData llid{}; // Read all lines of file for (InvoiceData id; ifs >> id; ) llid.add(id); // Print complete linked list llid.print(); } return 0; }
Ü请注意。我的链表不是通用的,并且末尾有一个空元素。您可以实现自己的链接列表,或从网上下载数千个示例之一。