读取和存储 CSV 数据
Read and Store CSV Data
我有这样的数据;
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、Description 和 Quantity。
我怎样才能从缓冲区中获取那列数据?
我只能使用 iostream、ctime、fstream、string 库来解决这些问题。没有向量。
首先,老师强迫人们在 C++ 中使用原始指针和 C 风格数组是一种耻辱。并且,为 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;
}
Ü租约。我的链接列表不是通用的,末尾有一个空元素。您可以实现自己的链表或从网上下载数以千计的示例之一。
我有这样的数据;
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、Description 和 Quantity。 我怎样才能从缓冲区中获取那列数据?
我只能使用 iostream、ctime、fstream、string 库来解决这些问题。没有向量。
首先,老师强迫人们在 C++ 中使用原始指针和 C 风格数组是一种耻辱。并且,为 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;
}
Ü租约。我的链接列表不是通用的,末尾有一个空元素。您可以实现自己的链表或从网上下载数以千计的示例之一。