2016-04-17 5 views
0

私のリストの範囲を表示しようとすると何らかの理由で余分な出力が得られます。プログラムはユーザーに表示する開始ノードと終了ノードの整数を入力するように要求し、何らかの理由で空白のノードを表示してから最初のノードを表示します。約10秒後、ノードの正しい範囲が表示されます。例えば表示中の余分な出力listnode in C++

、私は入力

ball, 4, 9.99 
doll, 2, 10.00 
lava lamp, 5, 24.99 

だろうが、それは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 

の2の範囲を考え入れたときに、これがかもしれなぜ誰でも知っていますか?

#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

* start *と* end *の入力はどうなったのですか? –

+0

は、先頭の –

答えて

1

(当該の機能が無効displayRangeである)あなたの問題の根本は、あなたがリストにセンチネルリンパ節を作成したが、その後displayRangeでそれを無視していないことです。 displayNodeに電話すると無視されます。遅れが表示される理由は、displayNodeのループが符号付き整数オーバーフロー(未定義の動作)に依存して終了するためです。範囲チェックの外にnodePtrのインクリメントを移動すると、これが解決されます。

このコードにはいくつかの問題があります。あなた自身のリストコンテナを実装しない理由はたくさんありますが、最も重要なのは、あなたが言語を経験していない限り、初めて正確に正しいものを得ることが難しいからです。 std::vectorをご覧になることを強くお勧めします。ここに私が見つけたアイテムのリストがあります。

  1. #define nullptr 0 Do not do this。この標準は、これが明確に定義された動作であることを保証するものではなく、2つのタイプが同じタイプではありません。
  2. cin.sync()を呼び出すことは、何もすることは保証されていません(実装が定義しています)。
  3. std::getlineを呼び出す前に、入力ストリームから空白を消去する必要があります。これはreference pageの「注意」に記載されています。
  4. 新しいノードを挿入するときは、newNode->nextをnullに設定する必要があります。
  5. コンパイラの警告をオンにします。初期化されていない変数をいくつか使用すると、未定義の動作につながる可能性があります。
+0

のポストを編集しました。NULLポインタの内部表現はすべて0である必要はありませんが、ポインタコンテキストの*リテラル* '0'はコンパイル時に内部NULLポインタ。例えば'while(p)'は 'while(p!= NULL)'と同じであることが保証されています。 '#define'はまだまだ悪い考えですが、まさにその理由ではありません。 –

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 
    } 
} 

、それは他のいくつかのバグを持っているのに。

ありがとうございます!

関連する問題