由于某些奇怪的原因,当我尝试显示列表的范围时,它会提供额外的输出。程序要求用户输入要显示的开始和结束节点整数,然后由于某种原因它将显示空白节点,然后显示第一个节点。大约10秒后,它将显示正确的节点范围。
例如,我会输入ball, 4, 9.99
doll, 2, 10.00
lava lamp, 5, 24.99
但是当说出2到3的范围时,它会输出
2. (blank), (blank), (blank)
3. ball, 4, 9.99
(pause for 10 seconds that is not called for)
2. doll, 2, 10.00
3. lava lamp, 5, 24.99
有谁知道为什么会这样? (有问题的函数是void displayRange)
#include <iostream>
#define nullptr 0
#include <cstdlib>
#include <algorithm>
#include <string>
#include <conio.h>
using namespace std;
int menu();
class ItemList {
private:
struct ListNode{
string IName;
string QQuantity;
string PPrice;
double value;
struct ListNode * next;
};
ListNode *head;
public:
ItemList()
{
head = new ListNode;
head->next=nullptr;
}
~ItemList();
void insertNode(string Item, string Quantity, string Price)
{
ListNode *newNode;
ListNode *nodePtr;
ListNode *previousNode=nullptr;
newNode=new ListNode;
newNode->IName=Item;
newNode->QQuantity=Quantity;
newNode->PPrice=Price;
if(!head)
{
head=newNode;
newNode->next=nullptr;
}
else
{
nodePtr=head;
previousNode=nullptr;
while(nodePtr != nullptr && nodePtr->IName < Item)
{
previousNode=nodePtr;
nodePtr=nodePtr->next;
}
if(previousNode==nullptr)
{
head=newNode;
newNode->next=nodePtr;
}
else
{
previousNode->next=newNode;
newNode->next=nodePtr;
}
}
}
void displayNode()
{
ListNode *nodePtr;
nodePtr=head->next;
int i=0;
while(nodePtr)
{
i++;
cout << i << ". " << nodePtr->IName << ", ";
cout << nodePtr->QQuantity << " ";
cout << "$" << nodePtr->PPrice << "\n" << endl;
nodePtr=nodePtr->next;
}
if(!head)
{
cout << "The store is empty." << endl;
}
}
void modifyNode(string Item)
{
ListNode *nodePtr;
ListNode *nodePrev;
string newName, newQuantity, newPrice;
int modify;
if (!head)
{
return;
cout << "Store is empty." << endl;
}
else
{
nodePtr = head;
if (head->IName==Item)
nodePtr = head->next;
else
{
while (nodePtr != nullptr && nodePtr->IName != Item)
{
nodePrev = nodePtr;
nodePtr = nodePtr->next;
}
}
if (nodePtr)
{
cout << nodePtr->IName << "\t" << nodePtr->QQuantity << "\t" << nodePtr->PPrice << endl;
cout << "What would you like to change?\n";
cout << "1. Item" << endl;
cout << "2. Quantity" << endl;
cout << "3. Price" << endl;
cout << "4. Whole Entry" << endl;
cin >> modify;
switch (modify)
{
case 1:
cout << "Change to what?\n";
cin.sync();
getline(cin,newName);
transform(newName.begin(), newName.end(), newName.begin(), ::toupper);
nodePtr->IName = newName;
break;
case 2:
cout << "Change to what?\n";
cin >> newQuantity;
transform(newQuantity.begin(), newQuantity.end(), newQuantity.begin(), ::toupper);
nodePtr->QQuantity = newQuantity;
break;
case 3:
cout << "Change to what?\n";
cin >> newPrice;
transform(newPrice.begin(), newPrice.end(), newPrice.begin(), ::toupper);
nodePtr->PPrice = newPrice;
break;
case 4:
cout << "What is the product called?\n";
cin.sync();
getline(cin,newName);
transform(newName.begin(), newName.end(), newName.begin(), ::toupper);
nodePtr->IName = newName;
cout << "How many are there really?\n";
cin >> newQuantity;
transform(newQuantity.begin(), newQuantity.end(), newQuantity.begin(), ::toupper);
nodePtr->QQuantity = newQuantity;
cout << "What is the actual price?\n";
cin >> newPrice;
transform(newPrice.begin(), newPrice.end(), newPrice.begin(), ::toupper);
nodePtr->PPrice = newPrice;
}
}
else
cout << "Product not found\n";
}
}
void deleteNode(string Item)
{
ListNode *nodePtr;
ListNode *previousNode;
if(!head)
return;
if(head->IName==Item)
{
nodePtr=head->next;
delete head;
head=nodePtr;
}
else
{
nodePtr=head;
while(nodePtr!=nullptr && nodePtr->IName!=Item)
{
previousNode=nodePtr;
nodePtr=nodePtr->next;
}
if(nodePtr)
{
previousNode->next=nodePtr->next;
delete nodePtr;
}
else
{
cout << "Nothing to delete." << endl;
}
}
}
void deleteRangeNode(int start, int stop)
{
ListNode *nodePtr;
ListNode *newNode;
nodePtr = head;
int i=-1;
cin.sync();
while(nodePtr!=nullptr)
{
i++;
if((i>=start)&&(i<=stop))
{
newNode->next = nodePtr -> next;
cout << "Deleted Product: " << nodePtr->IName << endl;
delete nodePtr;
nodePtr=newNode;
}
newNode=nodePtr;
nodePtr=nodePtr->next;
}
}
void displayRange(int start, int stop)
{
ListNode * nodePtr;
nodePtr=head;
int i=-1;
bool found=false;
cin.sync();
while(nodePtr!=nullptr)
{
i++;
if((i>=start && i<=stop))
{
cout << i << ". " << nodePtr->IName << ", ";
cout << nodePtr->QQuantity << " ";
cout << "$" << nodePtr->PPrice << "\n" << endl;
nodePtr=nodePtr->next;
}
}
}
};
ItemList::~ItemList()
{
ListNode *nodePtr;
ListNode *nextNode;
nodePtr=head;
while(nodePtr!=nullptr)
{
nextNode=nodePtr->next;
delete nodePtr;
nodePtr=nextNode;
}
}
int main()
{
ItemList pro;
int method;
while(method!=0)
{
int method=menu();
system("cls");
string It, Q, P;
int begin, end;
switch(method)
{
case 1:
int count;
cout << "How many products would you like to put in?" << endl;
cin >> count;
system("cls");
for(int i=0; i<count; i++)
{
cout << "Product #" << i + 1 << endl;
cout << "Enter the item name: ";
cin.sync();
getline(cin,It);
transform(It.begin(), It.end(), It.begin(), ::toupper);
cout << "Enter the Quantity: ";
cin >> Q;
transform(Q.begin(), Q.end(), Q.begin(), ::toupper);
cout << "Enter the Price: ";
cin >> P;
pro.insertNode(It, Q, P);
cout << "\n";
}
break;
case 2:
int dis;
cout << "How many products would you like to display?" << endl;
cout << "1. Entire Store" << endl;
cout << "2. Range of Products" << endl;
cin >> dis;
system("cls");
switch(dis)
{
case 1:
pro.displayNode();
break;
case 2:
cout << "The display should START at: ";
cin >> begin;
cout << "The display should END at: ";
cin >> end;
pro.displayRange(begin,end);
system("pause");
break;
}
break;
case 3:
pro.displayNode();
cout << "What product do you wish to modify? (by item name)" << endl;
cin.sync();
getline(cin, It);
transform(It.begin(), It.end(), It.begin(), ::toupper);
system("cls");
pro.modifyNode(It);
break;
case 4:
int del;
cout << "Do you wish to delete one product or more?" << endl;
cout << "1. One" << endl;
cout << "2. Range of Products" << endl;
cout << "3. Entire Store" << endl;
cin >> del;
system("cls");
switch(del)
{
case 1:
cout << "What product do you wish to delete? (by item name)" << endl;
pro.displayNode();
cout << "\n";
cin.sync();
getline(cin,It);
transform(It.begin(), It.end(), It.begin(), ::toupper);
pro.deleteNode(It);
cout << "\n";
break;
case 2:
pro.displayNode();
cout << "What range of items do you wish to delete?" << endl;
cout << "START: ";
cin >> begin;
cout << "STOP: ";
cin >> end;
pro.deleteRangeNode(begin, end);
break;
case 3:
pro.~ItemList();
cout << "All items deleted." << endl;
break;
}
break;
case 0:
cout << "Exiting the program." << endl;
return 0;
}
system("pause");
system("cls");
}
return 0;
}
int menu()
{
string space1= " ";
string space2= " ";
int method;
cout << space1 << "What would you like to do to the store?" << endl;
cout << space2 << "1. Add Product" << endl;
cout << space2 << "2. Display" << endl;
cout << space2 << "3. Modify Product" << endl;
cout << space2 << "4. Delete Product" << endl;
cout << space2 << "0. Exit\n" << endl;
cout << space2;
cin >> method;
return(method);
}
答案 0 :(得分:1)
问题的根源在于您在列表中创建了一个标记节点,但在displayRange
中没有忽略它。当你致电displayNode
时,你忽略了它。您看到延迟的原因是因为displayNode
中的循环依赖于有符号整数溢出(这是未定义的行为)来终止。将nodePtr
的增量移到范围检查之外将解决此问题。
此代码存在一些问题。有许多理由不实现自己的列表容器,但最重要的是因为除非您对该语言有经验,否则很难在第一次完全正确。我强烈建议你研究std::vector
。这是我找到的项目清单。
#define nullptr 0
不要这样做。该标准并不保证这是明确定义的行为,并且两者的类型不同。cin.sync()
可以执行任何操作(已定义实现)。std::getline
之前,您需要清除输入流中的空格。这将在“注释”下的reference page中介绍。newNode->next
设置为空。答案 1 :(得分:0)
空白节点的原因问题:插入在insertNode方法的head的下一个节点处开始。但是,显示从displayRange方法的头部开始。
解决方案:解决这种不匹配问题!您可以通过更改ItemList来解决此问题:
ItemList()
{
head = nullptr; //changed here
}
错误范围和延迟显示的原因问题:显示指针(nodePtr)未相应更新。
解决方案:解决这种不匹配问题!您可以通过更改displayRange来解决此问题,如下所示:
void displayRange(int start, int stop)
{
ListNode * nodePtr;
nodePtr = head;
int i = 0; //changed here
bool found = false;
cin.sync();
while (nodePtr != nullptr)
{
i++;
if ((i >= start && i <= stop))
{
cout << i << ". " << nodePtr->IName << ", ";
cout << nodePtr->QQuantity << " ";
cout << "$" << nodePtr->PPrice << "\n" << endl;
//nodePtr = nodePtr->next; //changed here
}
nodePtr = nodePtr->next; //changed here
}
}
我刚刚提到了提及问题的区域,虽然它还有其他一些错误。
谢谢!!!