Это программа типа сортировки слиянием.
Если вы посмотрите на самую нижнюю часть моего кода в main, когда я попытаюсь использовать cin, чтобы пользователь ввел целочисленную переменную «select», я думаю, что программа могла что-то получить из входного буфера. Я пробовал пару вещей, чтобы удалить что-нибудь из входного буфера, но мне не удалось это исправить. Программа пропускает cin >> select; как будто его там нет.
Я до сих пор не совсем знаком с тем, как ранее в программе использовал stringstream (ищите функцию Populate). Я думаю, это как-то связано с этим. Любое понимание будет очень признательно.
#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;
}
После того, как вы нажмете Ctrl + Z, чтобы завершить цикл в Populate
, входной поток будет в состоянии конца файла, и любые дальнейшие попытки ввода не удастся.
Таким образом, cin >> select;
в основном не будет пытаться что-либо прочитать, поскольку cin
сообщает, что он уже достиг конца ввода.
Есть ли простой способ исправить это без существенного изменения функции заполнения? Спасибо за Ваш ответ.
Скорее всего, вы делаете
getline
раньше, чемcin
.