1

This is a mergesort type program.

If you look at the very bottom of my code in main, when I try and use cin to have the user input an integer variable "select", I think the program might be getting something from the input buffer. I've tried a couple things to remove anything from the input buffer but haven't had any luck fixing this. The program seems to skip cin >> select; as if it's not there.

I'm still not completely familiar with how I used stringstream earlier in the program (look for the Populate function). I think this might have something to do with it. Any insight would be much appreciated.

#include "stdafx.h"
#include <string>
#include <iostream>

#include <fstream>
#include <sstream>
#include <iomanip>

using namespace std;
int printcount = 1;

class Node
{
public:
    string retailPrice;
    string wholesalePrice;
    string productName;

    Node * next;
    Node(string ins = "", string ins1 = "", string ins2 = "")  // Constructor - assigns new Links(Nodes) an empty title, and assigns the nullptr to "next"
        //indicating that there is no data stored in the following node i.e. "tail"
    {
        productName = ins;
        retailPrice = ins1;
        wholesalePrice = ins2;

        next = nullptr;
    }
};

class List
{
public:
    Node * productList; // "productList" is the address of the first node in the list. 
    List() { productList = nullptr; } // constructor - makes the address of the first node "productList" nullptr i.e. "head"

    bool IsEmpty() //If the address of the first node "theList" is null, returns true
    {
        return (productList == nullptr) ? true : false;
    }

    void Add(string ins, string ins1, string ins2)  //this function adds a new node to the beginning of the linked list. 
    {
        /* Node * Node1 = productList;    //Ask bob why this doesn't work
        while (Node1->next != nullptr) //searches for tail
        {
            Node1 = Node1->next; //Node1 points to the following node
        }

        Node * temp = new Node(ins); //Creates a new Node;
        Node1->next = temp; //assigns the old tail to point to the new node
        */ 

        Node * oldFirst = productList;  //initializies pointer "oldFirst" to point to the current address of the first node, "productList"
        productList = new Node(ins, ins1, ins2);    // creates a new node on the heap with string passed to Add function
                                    // theList is now the address of this new node.
        productList->next = oldFirst;   // the new header "productList"
    }

    void Remove(Node * thisOne) 
    {
        Node * guyBefore = FindTheGuyBefore(thisOne); 
        guyBefore = thisOne->next;  //assigns the "next" address of node preceding node to be deleted, to the address of the node following
                                    // the node to be deleted.
        thisOne->next = nullptr;
    }

    int Populate()
    {
        //cin.ignore();
        string input;
        int count = 0;
        while (getline(cin, input))
        {
            stringstream ss(input);
            getline(ss, input, ',');
            string s = input; //name of product
            ss >> ws;
            getline(ss, input, ',');
            string s1 = input;  //retail price
            ss >> ws;
            getline(ss, input);
            string s2 = input;  //wholesale price
            count++;

            Add(s, s1, s2);
        }

        /*
        char buffer[120];
        string buf(buffer);
        int count = 0;
        while (getline(cin, buf))
        {
            Add(buf);
            count++;
        }
        */
        return count;
    }

    void Visit(void(*fp)(string s, string s1, string s2)) //visits all nodes and applies a void function to a string
    {   
        int count1 = 0;
        Node * currentNode = productList; //assigns 'curLink' the address of 'theList'
        while (currentNode != nullptr) //loop goes until it reaches the tail of the linked list
        {
            (*fp)(currentNode->retailPrice, currentNode->wholesalePrice, currentNode->productName); //applies the function to the title of the node


            currentNode = currentNode->next; //assigns address of 'curLink' the address of the following node
            ++count1;
        }
    }

    void MergeSort(int select)
    {
        if (productList == nullptr) return;         // if the list is empty, terminate the function (sort unnecessary)
        if (productList->next == nullptr) return;   // if there is only one item in the list, terminate the function (sort unnecessary)
        List list1;                                 // Instantiate two lists
        List list2;
        Split(list1, list2);                        // This should leave productList == nullptr. Splits theList into two lists. 
        list1.MergeSort(select);                            //  Performs the MergeSort operation 
        list2.MergeSort(select);                        
        Merge(list1, list2, select);
    }


private:


    Node * FindTheGuyBefore(Node * thisOne)
    {
        Node * aNode = productList;                 //aLink points to productList, the address of the first node
        while (aNode->next != thisOne)              //looks through the list until the address stored in "next" is the address of the value
                                                    //preceding 'thisOne', assigns aLink the value of that address
            aNode = aNode->next;        
        return aNode;

    }

    Node * GetHeadNode()                            //returns the address of the head of the linked list
    {
        Node * answer = productList;                //answer holds the address of theList
        if (answer != nullptr)                      //if the address of theList is not a null pointer
        {
            productList = answer->next;             //theList is now the address of the following node
            answer->next = nullptr;                 //answer points to the nullptr
        }
        return answer;
    }

    void Push(Node * new1)                          //inserts a node at the beginning of the linked list
    {
        if (new1 == nullptr) return;                // nothing to add 
        new1->next = productList;                   // the address pointed to by new1 is the address of the head
        productList = new1;                         // new1 is now the head
    }

    void Split(List & list1, List & list2)          //inserts null pointers between items in a list
    {
        Node * cur0 = nullptr;
        bool left = true;
        while (productList != nullptr)
        {
            cur0 = GetHeadNode();                   //cur0 is the head of the linked list

            if (left)                               // Add cur0 link to the start of list1
            {
                list1.Push(cur0);                   //inserts a node where the value of next is nullptr; essentially splitting the list
                left = false;
            }
            else                                    // Add cur0 link to the start of list2
            {
                list2.Push(cur0);
                left = true;
            }
        }
    }

    Node * GetSmaller(List & otherList, int select)
    {  // Will extra smaller head node from  this List or otherList 
        Node * head1 = productList;
        Node * head2 = otherList.productList;
        if (head1 == nullptr) return otherList.GetHeadNode();
        if (head2 == nullptr) return GetHeadNode();

        if (select == 1)
        {
            if ((head1->productName) < (head2->productName)) return GetHeadNode();
        }

        else if (select == 2)
        {
            if ((head1->retailPrice) < (head2->retailPrice)) return GetHeadNode();
        }

        else if (select == 3)
        {
            if ((head1->wholesalePrice) < (head2->wholesalePrice)) return GetHeadNode();
        }
        return otherList.GetHeadNode();
    }

    void Merge(List & list1, List & list2, int select)
    {// Assumes productList == nullptr
        Node * new1 = list1.GetSmaller(list2, select);      
        productList = new1;  // First guy in list or nullptr
        Node * cur0 = productList; // this must point to last elt added to theList (empty due to split)
        while ((new1 = list1.GetSmaller(list2, select)) != nullptr)
        {
            cur0->next = new1;
            new1->next = nullptr;
            cur0 = new1;
        }
    }
};

void print(string s, string s1, string s2)
{
    cout << "Product # " << printcount << endl;
    cout << left << setw(20) << "Product Name: " << left << setw(20) << s2 << endl;
    cout << left << setw(20) << "Retail Price: " << left << setw(20) << s << endl;
    cout << left << setw(20) << "Wholesale Price: " << left << setw(20) << s1 << endl << endl;
    ++printcount;
};

int main()
    {
        List myProductList;
        cout << "****************************************************************************************************" << endl
            << "           PROGRAM FOR SORTING INVENTORY BY PRODUCT NAME, RETAIL PRICE, OR WHOLESALE PRICE          " << endl
            << "****************************************************************************************************" << endl << endl;

        //POPULATE THE LIST
        cout << "Enter the name, retail price, and wholesale price of a product in that order, seperated by commas." << endl;
        cout << "You may enter multiple products. Seperate each product with a return. When you have finished entering items, enter CTRL-Z. " << endl << endl;
        myProductList.Populate();

        cout << "Would you like to:" << endl << endl;
        cout << "1.  Display your list." << endl;
        cout << "2.  Sort your list." << endl;
        cout << "3.  Add an item to your list." << endl;
        cout << "4.  Delete an item from your list." << endl;
        cout << "5.  Modify an item on your list." << endl;
        cout << "6.  Determine whether your list is empty." << endl << endl << "Enter an integer." << endl << endl;

        int select; 
        cin >> select;



        system("Pause");
        return 0;
    }
wsamples
  • 11
  • 2

1 Answers1

0

After you enter Ctrl+Z to end the loop in Populate the input stream will be in an end-of-file state, and any further input attempts will fail.

So cin >> select; in main will not try to read anything as cin reports that it has already reached the end of input.

Bo Persson
  • 86,087
  • 31
  • 138
  • 198
  • Is there an easy way to rectify this without substantially modifying the Populate function? Thanks for your answer. – wsamples Apr 09 '18 at 01:54