打印列表功能不从 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++;
}