打印列表功能不从 CSV 文件输出数据
Print List function is not outputting data from CSV file
我正在处理链表作业。 Load Bids 函数从 CSV 文件中提取数据。 Print List 函数应该将列表中的所有出价条目打印到控制台。出于某种原因,每当我 select 加载投标选项,然后从菜单中选择打印列表选项时,打印列表功能不会输出数据,即使在我调用加载投标功能之后也是如此。它只是打印默认构造函数的默认值,这基本上什么都没有。 Print List 函数似乎编写正确,但数据似乎在某处丢失了。有人可以帮我解决这个问题吗?
#include <algorithm>
#include <iostream>
#include <time.h>
#include "CSVparser.hpp"
using namespace std;
//============================================================================
// Global definitions visible to all methods and classes
//============================================================================
// forward declarations
double strToDouble(string str, char ch);
// define a structure to hold bid information
struct Bid {
string bidId; // unique identifier
string title;
string fund;
double amount;
Bid() {
amount = 0.0;
}
};
//============================================================================
// Linked-List class definition
//============================================================================
/**
* Define a class containing data members and methods to
* implement a linked-list.
*/
class LinkedList {
private:
//Internal structure for list entries, housekeeping variables
struct Node {
Bid bid;
Node *next;
// default constructor
Node() {
next = nullptr;
}
// initialize with a bid
Node(Bid aBid) {
bid = aBid;
next = nullptr;
}
};
Node* head;
Node* tail;
int size = 0;
public:
LinkedList();
virtual ~LinkedList();
void Append(Bid bid);
void Prepend(Bid bid);
void PrintList();
void Remove(string bidId);
Bid Search(string bidId);
int Size();
};
/**
* Default constructor
*/
LinkedList::LinkedList() {
// FIXME (1): Initialize housekeeping variables
//set head and tail equal to null
head = nullptr;
tail = nullptr;
}
/**
* Destructor
*/
LinkedList::~LinkedList() {
// start at the head
Node* current = head;
Node* temp;
// loop over each node, detach from list then delete
while (current != nullptr) {
temp = current; // hang on to current node
current = current->next; // make current the next node
delete temp; // delete the orphan node
}
}
/**
* Append a new bid to the end of the list
*/
void LinkedList::Append(Bid bid) {
// FIXME (2): Implement append logic
//Create new node
Node* new_node = new Node;
//if there is nothing at the head...
if (head == nullptr) {
// new node becomes the head and the tail
head = new_node;
tail = new_node;
}
//else
else {
// make current tail node point to the new node
tail->next = new_node;
// and tail becomes the new node
tail = new_node;
}
//increase size count
size++;
}
/**
* Prepend a new bid to the start of the list
*/
void LinkedList::Prepend(Bid bid) {
// FIXME (3): Implement prepend logic
// Create new node
Node* new_node = new Node;
// if there is already something at the head...
if (head != nullptr) {
// new node points to current head as its next node
new_node->next = head;
}
// head now becomes the new node
head = new_node;
//increase size count
size++;
}
/**
* Simple output of all bids in the list
*/
void LinkedList::PrintList() {
// FIXME (4): Implement print logic
// start at the head
Node* current = head;
// while loop over each node looking for a match
while (current != nullptr) {
//output current bidID, title, amount and fund
cout << current->bid.bidId << " | ";
cout << current->bid.title << " | ";
cout << current->bid.amount << " | ";
cout << current->bid.fund << endl;
//set current equal to next
current = current->next;
}
}
/**
* Remove a specified bid
*
* @param bidId The bid id to remove from the list
*/
void LinkedList::Remove(string bidId) {
// FIXME (5): Implement remove logic
// special case if matching node is the head
if (head->bid.bidId == bidId) {
// make head point to the next node in the list
head->next;
//decrease size count
size--;
//return
return;
}
// start at the head
Node* current = head;
Node* temp = nullptr;
// while loop over each node looking for a match
while (current != nullptr) {
// if the next node bidID is equal to the current bidID
if (current->next->bid.bidId == current->bid.bidId) {
// hold onto the next node temporarily
temp = current->next;
}
// make current node point beyond the next node
current->next->next;
// now free up memory held by temp
free(temp);
// decrease size count
size--;
//return
return;
}
// curretn node is equal to next node
current = current->next;
}
/**
* Search for the specified bidId
*
* @param bidId The bid id to search for
*/
Bid LinkedList::Search(string bidId) {
// FIXME (6): Implement search logic
// special case if matching node is the head
if (head->bid.bidId == bidId) {
// make head point to the next node in the list
head->next;
//decrease size count
size--;
//return
return head->bid;
}
// start at the head of the list
Node* current = head;
// keep searching until end reached with while loop (next != nullptr
while (current != nullptr) {
// if the current node matches, return it
if (current->bid.bidId == bidId) {
return current->bid;
}
// else current node is equal to next node
else {
current = current->next;
}
}
//return bid
return current->bid;
}
/**
* Returns the current size (number of elements) in the list
*/
int LinkedList::Size() {
return size;
}
//============================================================================
// Static methods used for testing
//============================================================================
/**
* Display the bid information
*
* @param bid struct containing the bid info
*/
void displayBid(Bid bid) {
cout << bid.bidId << ": " << bid.title << " | " << bid.amount
<< " | " << bid.fund << endl;
return;
}
/**
* Prompt user for bid information
*
* @return Bid struct containing the bid info
*/
Bid getBid() {
Bid bid;
cout << "Enter Id: ";
cin.ignore();
getline(cin, bid.bidId);
cout << "Enter title: ";
getline(cin, bid.title);
cout << "Enter fund: ";
cin >> bid.fund;
cout << "Enter amount: ";
cin.ignore();
string strAmount;
getline(cin, strAmount);
bid.amount = strToDouble(strAmount, '$');
return bid;
}
/**
* Load a CSV file containing bids into a LinkedList
*
* @return a LinkedList containing all the bids read
*/
void loadBids(string csvPath, LinkedList *list) {
cout << "Loading CSV file " << csvPath << endl;
// initialize the CSV Parser
csv::Parser file = csv::Parser(csvPath);
try {
// loop to read rows of a CSV file
for (int i = 0; i < file.rowCount(); i++) {
// initialize a bid using data from current row (i)
Bid bid;
bid.bidId = file[i][1];
bid.title = file[i][0];
bid.fund = file[i][8];
bid.amount = strToDouble(file[i][4], '$');
// cout << bid.bidId << ": " << bid.title << " | " << bid.fund << " | " <<
bid.amount << endl;
// add this bid to the end
list->Append(bid);
}
} catch (csv::Error &e) {
std::cerr << e.what() << std::endl;
}
}
/**
* Simple C function to convert a string to a double
* after stripping out unwanted char
*
* credit:
*
* @param ch The character to strip out
*/
double strToDouble(string str, char ch) {
str.erase(remove(str.begin(), str.end(), ch), str.end());
return atof(str.c_str());
}
/**
* The one and only main() method
*
* @param arg[1] path to CSV file to load from (optional)
* @param arg[2] the bid Id to use when searching the list (optional)
*/
int main(int argc, char* argv[]) {
// process command line arguments
string csvPath, bidKey;
switch (argc) {
case 2:
csvPath = argv[1];
bidKey = "98109";
break;
case 3:
csvPath = argv[1];
bidKey = argv[2];
break;
default:
csvPath = "eBid_Monthly_Sales_Dec_2016.csv";
bidKey = "98109";
}
clock_t ticks;
LinkedList bidList;
Bid bid;
int choice = 0;
while (choice != 9) {
cout << "Menu:" << endl;
cout << " 1. Enter a Bid" << endl;
cout << " 2. Load Bids" << endl;
cout << " 3. Display All Bids" << endl;
cout << " 4. Find Bid" << endl;
cout << " 5. Remove Bid" << endl;
cout << " 9. Exit" << endl;
cout << "Enter choice: ";
cin >> choice;
switch (choice) {
case 1:
bid = getBid();
bidList.Append(bid);
displayBid(bid);
break;
case 2:
ticks = clock();
loadBids(csvPath, &bidList);
cout << bidList.Size() << " bids read" << endl;
ticks = clock() - ticks; // current clock ticks minus starting clock ticks
cout << "time: " << ticks << " milliseconds" << endl;
cout << "time: " << ticks * 1.0 / CLOCKS_PER_SEC << " seconds" << endl;
break;
case 3:
bidList.PrintList();
break;
case 4:
ticks = clock();
bid = bidList.Search(bidKey);
ticks = clock() - ticks; // current clock ticks minus starting clock ticks
if (!bid.bidId.empty()) {
displayBid(bid);
} else {
cout << "Bid Id " << bidKey << " not found." << endl;
}
cout << "time: " << ticks << " clock ticks" << endl;
cout << "time: " << ticks * 1.0 / CLOCKS_PER_SEC << " seconds" << endl;
break;
case 5:
bidList.Remove(bidKey);
break;
}
}
cout << "Good bye." << endl;
return 0;
}
我通过在创建新节点后添加几行来更改 Append 函数,看起来问题已解决。这是新功能。
void LinkedList::Append(Bid bid) {
// FIXME (2): Implement append logic
//Create new node
Node* new_node = new Node;
new_node->bid = bid;
new_node->next = nullptr;
//if there is nothing at the head...
if (head == nullptr) {
// new node becomes the head and the tail
head = new_node;
tail = new_node;
}
//else
else {
// make current tail node point to the new node
tail->next = new_node;
// and tail becomes the new node
tail = new_node;
}
//increase size count
size++;
}
我正在处理链表作业。 Load Bids 函数从 CSV 文件中提取数据。 Print List 函数应该将列表中的所有出价条目打印到控制台。出于某种原因,每当我 select 加载投标选项,然后从菜单中选择打印列表选项时,打印列表功能不会输出数据,即使在我调用加载投标功能之后也是如此。它只是打印默认构造函数的默认值,这基本上什么都没有。 Print List 函数似乎编写正确,但数据似乎在某处丢失了。有人可以帮我解决这个问题吗?
#include <algorithm>
#include <iostream>
#include <time.h>
#include "CSVparser.hpp"
using namespace std;
//============================================================================
// Global definitions visible to all methods and classes
//============================================================================
// forward declarations
double strToDouble(string str, char ch);
// define a structure to hold bid information
struct Bid {
string bidId; // unique identifier
string title;
string fund;
double amount;
Bid() {
amount = 0.0;
}
};
//============================================================================
// Linked-List class definition
//============================================================================
/**
* Define a class containing data members and methods to
* implement a linked-list.
*/
class LinkedList {
private:
//Internal structure for list entries, housekeeping variables
struct Node {
Bid bid;
Node *next;
// default constructor
Node() {
next = nullptr;
}
// initialize with a bid
Node(Bid aBid) {
bid = aBid;
next = nullptr;
}
};
Node* head;
Node* tail;
int size = 0;
public:
LinkedList();
virtual ~LinkedList();
void Append(Bid bid);
void Prepend(Bid bid);
void PrintList();
void Remove(string bidId);
Bid Search(string bidId);
int Size();
};
/**
* Default constructor
*/
LinkedList::LinkedList() {
// FIXME (1): Initialize housekeeping variables
//set head and tail equal to null
head = nullptr;
tail = nullptr;
}
/**
* Destructor
*/
LinkedList::~LinkedList() {
// start at the head
Node* current = head;
Node* temp;
// loop over each node, detach from list then delete
while (current != nullptr) {
temp = current; // hang on to current node
current = current->next; // make current the next node
delete temp; // delete the orphan node
}
}
/**
* Append a new bid to the end of the list
*/
void LinkedList::Append(Bid bid) {
// FIXME (2): Implement append logic
//Create new node
Node* new_node = new Node;
//if there is nothing at the head...
if (head == nullptr) {
// new node becomes the head and the tail
head = new_node;
tail = new_node;
}
//else
else {
// make current tail node point to the new node
tail->next = new_node;
// and tail becomes the new node
tail = new_node;
}
//increase size count
size++;
}
/**
* Prepend a new bid to the start of the list
*/
void LinkedList::Prepend(Bid bid) {
// FIXME (3): Implement prepend logic
// Create new node
Node* new_node = new Node;
// if there is already something at the head...
if (head != nullptr) {
// new node points to current head as its next node
new_node->next = head;
}
// head now becomes the new node
head = new_node;
//increase size count
size++;
}
/**
* Simple output of all bids in the list
*/
void LinkedList::PrintList() {
// FIXME (4): Implement print logic
// start at the head
Node* current = head;
// while loop over each node looking for a match
while (current != nullptr) {
//output current bidID, title, amount and fund
cout << current->bid.bidId << " | ";
cout << current->bid.title << " | ";
cout << current->bid.amount << " | ";
cout << current->bid.fund << endl;
//set current equal to next
current = current->next;
}
}
/**
* Remove a specified bid
*
* @param bidId The bid id to remove from the list
*/
void LinkedList::Remove(string bidId) {
// FIXME (5): Implement remove logic
// special case if matching node is the head
if (head->bid.bidId == bidId) {
// make head point to the next node in the list
head->next;
//decrease size count
size--;
//return
return;
}
// start at the head
Node* current = head;
Node* temp = nullptr;
// while loop over each node looking for a match
while (current != nullptr) {
// if the next node bidID is equal to the current bidID
if (current->next->bid.bidId == current->bid.bidId) {
// hold onto the next node temporarily
temp = current->next;
}
// make current node point beyond the next node
current->next->next;
// now free up memory held by temp
free(temp);
// decrease size count
size--;
//return
return;
}
// curretn node is equal to next node
current = current->next;
}
/**
* Search for the specified bidId
*
* @param bidId The bid id to search for
*/
Bid LinkedList::Search(string bidId) {
// FIXME (6): Implement search logic
// special case if matching node is the head
if (head->bid.bidId == bidId) {
// make head point to the next node in the list
head->next;
//decrease size count
size--;
//return
return head->bid;
}
// start at the head of the list
Node* current = head;
// keep searching until end reached with while loop (next != nullptr
while (current != nullptr) {
// if the current node matches, return it
if (current->bid.bidId == bidId) {
return current->bid;
}
// else current node is equal to next node
else {
current = current->next;
}
}
//return bid
return current->bid;
}
/**
* Returns the current size (number of elements) in the list
*/
int LinkedList::Size() {
return size;
}
//============================================================================
// Static methods used for testing
//============================================================================
/**
* Display the bid information
*
* @param bid struct containing the bid info
*/
void displayBid(Bid bid) {
cout << bid.bidId << ": " << bid.title << " | " << bid.amount
<< " | " << bid.fund << endl;
return;
}
/**
* Prompt user for bid information
*
* @return Bid struct containing the bid info
*/
Bid getBid() {
Bid bid;
cout << "Enter Id: ";
cin.ignore();
getline(cin, bid.bidId);
cout << "Enter title: ";
getline(cin, bid.title);
cout << "Enter fund: ";
cin >> bid.fund;
cout << "Enter amount: ";
cin.ignore();
string strAmount;
getline(cin, strAmount);
bid.amount = strToDouble(strAmount, '$');
return bid;
}
/**
* Load a CSV file containing bids into a LinkedList
*
* @return a LinkedList containing all the bids read
*/
void loadBids(string csvPath, LinkedList *list) {
cout << "Loading CSV file " << csvPath << endl;
// initialize the CSV Parser
csv::Parser file = csv::Parser(csvPath);
try {
// loop to read rows of a CSV file
for (int i = 0; i < file.rowCount(); i++) {
// initialize a bid using data from current row (i)
Bid bid;
bid.bidId = file[i][1];
bid.title = file[i][0];
bid.fund = file[i][8];
bid.amount = strToDouble(file[i][4], '$');
// cout << bid.bidId << ": " << bid.title << " | " << bid.fund << " | " <<
bid.amount << endl;
// add this bid to the end
list->Append(bid);
}
} catch (csv::Error &e) {
std::cerr << e.what() << std::endl;
}
}
/**
* Simple C function to convert a string to a double
* after stripping out unwanted char
*
* credit:
*
* @param ch The character to strip out
*/
double strToDouble(string str, char ch) {
str.erase(remove(str.begin(), str.end(), ch), str.end());
return atof(str.c_str());
}
/**
* The one and only main() method
*
* @param arg[1] path to CSV file to load from (optional)
* @param arg[2] the bid Id to use when searching the list (optional)
*/
int main(int argc, char* argv[]) {
// process command line arguments
string csvPath, bidKey;
switch (argc) {
case 2:
csvPath = argv[1];
bidKey = "98109";
break;
case 3:
csvPath = argv[1];
bidKey = argv[2];
break;
default:
csvPath = "eBid_Monthly_Sales_Dec_2016.csv";
bidKey = "98109";
}
clock_t ticks;
LinkedList bidList;
Bid bid;
int choice = 0;
while (choice != 9) {
cout << "Menu:" << endl;
cout << " 1. Enter a Bid" << endl;
cout << " 2. Load Bids" << endl;
cout << " 3. Display All Bids" << endl;
cout << " 4. Find Bid" << endl;
cout << " 5. Remove Bid" << endl;
cout << " 9. Exit" << endl;
cout << "Enter choice: ";
cin >> choice;
switch (choice) {
case 1:
bid = getBid();
bidList.Append(bid);
displayBid(bid);
break;
case 2:
ticks = clock();
loadBids(csvPath, &bidList);
cout << bidList.Size() << " bids read" << endl;
ticks = clock() - ticks; // current clock ticks minus starting clock ticks
cout << "time: " << ticks << " milliseconds" << endl;
cout << "time: " << ticks * 1.0 / CLOCKS_PER_SEC << " seconds" << endl;
break;
case 3:
bidList.PrintList();
break;
case 4:
ticks = clock();
bid = bidList.Search(bidKey);
ticks = clock() - ticks; // current clock ticks minus starting clock ticks
if (!bid.bidId.empty()) {
displayBid(bid);
} else {
cout << "Bid Id " << bidKey << " not found." << endl;
}
cout << "time: " << ticks << " clock ticks" << endl;
cout << "time: " << ticks * 1.0 / CLOCKS_PER_SEC << " seconds" << endl;
break;
case 5:
bidList.Remove(bidKey);
break;
}
}
cout << "Good bye." << endl;
return 0;
}
我通过在创建新节点后添加几行来更改 Append 函数,看起来问题已解决。这是新功能。
void LinkedList::Append(Bid bid) {
// FIXME (2): Implement append logic
//Create new node
Node* new_node = new Node;
new_node->bid = bid;
new_node->next = nullptr;
//if there is nothing at the head...
if (head == nullptr) {
// new node becomes the head and the tail
head = new_node;
tail = new_node;
}
//else
else {
// make current tail node point to the new node
tail->next = new_node;
// and tail becomes the new node
tail = new_node;
}
//increase size count
size++;
}