堆栈程序打印功能无法正常工作

时间:2011-09-29 23:38:13

标签: c++ pointers stack nodes

我刚刚完成了这个程序的工作,但从一开始我注意到它不知何故打印出它应该的一切。 需要首先从顶部开始打印堆栈中的整数,然后从底部开始再次执行。 它正确打印从上到下,但由于某种原因,它只打印从底部到顶部的最底部数字。 例如,如果堆栈包含整数1,2,3,4,5,6, 其中1位于堆栈的底部,6位于顶部。 该程序应打印以下内容: 顶部{6 5 4 3 2 1}底部底部{1 2 3 4 5 6}顶部

但它会打印以下内容: 顶部{6 5 4 3 2 1}底部{1}顶部

这是打印功能:

void Print() const     
// Prints stack contents to stdout in both top-to-bottom and bottom-to-top order 
{                      
  Node* temp = topPtr; 
  cout << "Top { ";

  // Forward print
  while (temp != NULL)
  {
    cout << temp->data << " "; 

    if (temp->next == NULL)
      break; 

    temp = temp->next;
  }
  cout << "} Bottom      Bottom { ";

  // Reverse print
  while (temp != NULL)
  {
    cout << temp->data << " ";  
    temp = temp->previous;
  }
  cout << "} Top" << endl;
} // End Print()

}; //结束类堆栈

如果你需要任何进一步的参考,那么是main()

#include <iostream>
#include <fstream>
#include <new>
#include <cstddef>
#include "stack.h"

using namespace std;

int main(int argc, char* argv[])
{
   ifstream inputs;                  // Input file for commands
   char op;                              // Hold operation and        optional char input
  int value;                        // Value input from file
  string comment;                   // Holds comment from file
  Stack* sPtr = NULL;                  // Will point to stack object

  // Output usage message if one input file name is not provided
  if (argc != 2)
      {
        cout << "Usage:\n  project03  <inputfile>\n";
    return 1;
  }

  // Attempt to open input file -- terminate if file does not open
  inputs.open(argv[1]);
  if (!inputs)
  {
    cout << "Error - unable to open input file" << endl;
return 1;
  }

  // Input and echo header comment from file
  getline(inputs, comment);          // Input and echo the comment appearing in the test   file
  cout << endl << '#' << comment << endl;   

  // Process commands from input file
  inputs >> op;                     // Attempt to input first command
  while (inputs)
  {
    switch (op)                     // Process operation input from file
    {
      case '#':  // Test file comment
                 getline(inputs, comment);     // Input and echo the comment appearing in the test file
             cout << '#' << comment << endl;
             break;

  case 'c':  // Constructor
             cout << endl << "Stack( )";
             try
             {
               sPtr = new Stack( );    // Attempt to create an empty stack object
               cout << " -- Successful" << endl;
             }
             catch ( std::bad_alloc )
             {
               cout << "Failed : Terminating now..." << endl;
               return 1;
             }
             break;

  case '+':  // Push
             inputs >> value;
             cout << "Push(" << value << ")";
             try
             {
               sPtr->Push(value);
               cout << " -- successful";
             }
             catch (StackFull)
             {
               cout << " -- Failed Full Stack"; 
             }
             cout << endl;
             break;

  case '-':  // Pop
             cout << "Pop() -- ";
             try
             {
               sPtr->Pop();
               cout << "successful";
             }
             catch (StackEmpty)
             {
               cout << "Failed Empty Stack";
             }
             cout << endl;
             break;

  case 'f':   // IsFull
             cout << "IsFull() -- ";
             try
             {
                if (sPtr->IsFull())
                  cout << "true";
                else
                  cout << "false";
             }
             catch ( ... )
             {
               cout << "operation failed";
             }
             cout << endl;
             break;

  case 'e':   // IsEmpty
             cout << "IsEmpty() -- ";
             try
             {
                  if (sPtr->IsEmpty())
                       cout << "true";
                  else
                       cout << "false";
             }
             catch ( ... )
             {
                  cout << "operation failed";
             }
             cout << endl;
             break;

  case 'm':   // Make Empty
             sPtr->MakeEmpty();
             cout << "MakeEmpty()" << endl;
             break;         

  case 'p':  // Print Stack
             cout << "Print() -- ";
             sPtr->Print(); 
             break;

  case 't':  // Top of Stack
             try
             {
               cout << "Top() -- " << sPtr->Top() << endl;
             }
             catch (StackEmpty)
             {
               cout << "Top() -- Failed Empty Stack" << endl;
             }
             break;

  case '>':   // Max value within Stack
             try
             {
                  cout << "Max() -- " << sPtr->Max() << endl;
             }
             catch (StackEmpty)
             {
                  cout << "Max() -- Failed Empty Stack" << endl;
             }
             break; 

  case '<':   // Min value within Stack
             try
             {
                  cout << "Min() -- " << sPtr->Min() << endl;
             }
             catch (StackEmpty)
             {
                  cout << "Min() -- Failed Empty Stack" << endl;
             }
             break; 

  case '?':  // Peek(n) Stack
             inputs >> value;
             try
             {
               cout << "Peek(" << value << ") -- " << sPtr->Peek(value) << endl;  
             }
             catch (StackInvalidPeek)
             {
               cout << "Peek(" << value << ") -- Failed Invalid Peek" << endl;
             }
             break;

  case 's':  // Size of Stack
             cout << "Size() -- " << sPtr->Size() << endl;  
             break;

  case 'd':  // Destructor
             delete sPtr;
             sPtr = NULL;
             cout << "~Stack()" << endl << endl;
             break;

  default:   // Error
             cout << "Error - unrecognized operation '" << op << "'" << endl;
             cout << "Terminating now..." << endl;
             return 1;
             break;
}

inputs >> op;   // Attempt to input next command
 }

  return 0;
} // End main()

这里是stack.cpp(stack.h)的头文件

//
// stack.h
//
// Specification file for Stack class, a stack of integers implemented
// using doubly-linked nodes.
//
// ***** DO NOT MODIFY THIS FILE *****
 //
#include <iostream>
using namespace std;


#ifndef STACK_H
#define STACK_H

class StackEmpty        {  /* No Code */  };
// StackEmpty exception class - throw an object of this type when stack is empty
// Hint: there is no code for exception classes

class StackFull         {  /* No Code */  };
// StackFull exception class - throw an object of this type when stack is full

class StackInvalidPeek  {  /* No Code */  };
// StackInvalidPeek exception class - throw an object of this type when invalid peek    position is used


struct Node                // Node data type for storing a single stack entry along with   pointers to
{                          // neighboring entries (previous and next) in the stack
  Node* previous;          // Member variable that holds the address of the predessor node in the stack sequence
  Node* next;              // Member variable that holds the address of the successor node in the stack sequence
  int   data;              // Member variable that holds the data value
};


class Stack                // Implements stack of integers ADT using doubly-linked sequence of nodes
{
  private:
  Node* topPtr;          // Points to the top node on the stack array

 public:
Stack();               // Default constructor initializes empty stack


~Stack();              // Destructor deallocates all nodes from stack 
                       // Must not create a memory leak

void Push(int n);      // Pushes integer n onto top of stack.  
                       // If unable to push, throws StackFull exception.

void Pop();            // Removes top integer from stack
                       // If stack is already empty, throws StackEmpty exception

bool IsEmpty() const;  // Returns true if stack is empty; false otherwise


bool IsFull() const;   // Returns true if stack is full; false otherwise


void MakeEmpty();      // Removes all nodes from stack leaving an empty, but usable stack
                       // Must not create a memory leak

int Top() const;       // Returns value of top integer on stack WITHOUT modifying the stack
                       // If stack is empty, throws StackEmpty exception

int Size() const;      // Returns number of items on stack WITHOUT modifying the stack


int Max() const;       // Returns value of largest integer within stack WITHOUT modifying the stack
                       // If stack is empty, throws StackEmpty

int Min() const;       // Returns value of smallest integer within stack WITHOUT modifying the stack
                       // If stack is empty, throws StackEmpty

int Peek( int n) const; // Returns stack value n levels down from top of stack. Peek(0) = Top()
                         // If position n does not exist, throws StackInvalidPeek


    .   ./*******  DO NOT MODIFY ANY OF THE CODE FOR PRINT()             *******/
/******   DO NOT PLACE A COPY OF PRINT() CODE IN STACK.CPP!!!   *******/

void Print() const     
// Prints stack contents to stdout in both top-to-bottom and bottom-to-top order 
{                      
  Node* temp = topPtr; 
  cout << "Top { ";

  // Forward print
  while (temp != NULL)
  {
    cout << temp->data << " "; 

    if (temp->next == NULL)
      break; 

    temp = temp->next;
  }
  cout << "} Bottom      Bottom { ";

  // Reverse print
  while (temp != NULL)
  {
    cout << temp->data << " ";  
    temp = temp->previous;
  }
  cout << "} Top" << endl;
} // End Print()

};  // End Class Stack

#endif

最后这里是stack.cpp,这是我创建的文件,其余的是给出的。

//
//  stack.cpp
//  
//
//  Created by Otapia on 9/19/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#include <iostream>
#include <new>
#include "stack.h"

Stack::Stack()          // Default constructor initializes empty stack
{
topPtr = NULL;
}

Stack::~Stack()         // Destructor deallocates all nodes from stack 
                    // Must not create a memory leak
{
Node* tempPtr;
while ( topPtr != NULL ) 
{
tempPtr = topPtr;
topPtr = topPtr->next;
delete tempPtr;
}
}

void Stack::Push(int n) // Pushes integer n onto top of stack.  
                    // If unable to push, throws StackFull exception.
{
if(!IsFull())
{

 Node* tempPtr = new Node;
 tempPtr->data = n;
 tempPtr->next = topPtr;
 topPtr = tempPtr;

}
else
throw IsFull();
}

void Stack::Pop()       // Removes top integer from stack
                    // If stack is already empty, throws StackEmpty exception
{
    if (!IsEmpty())
    {
   Node* tempPtr;
  tempPtr = topPtr;
  topPtr = topPtr->next;
  delete tempPtr;
}
else
throw StackEmpty();
}

bool Stack::IsEmpty() const // Returns true if stack is empty; false otherwise
{

    return(topPtr == NULL);

}

bool Stack::IsFull() const  // Returns true if stack is full; false otherwise
{

Node* location;
try
{
location = new Node;
delete location;
return false;
} 
catch(std::bad_alloc) 

{return true; }

}

void Stack::MakeEmpty() // Removes all nodes from stack leaving an empty, but usable stack
                    // Must not create memory leak
{

    Node* tempPtr;
    while ( topPtr != NULL ) {
    tempPtr = topPtr;
    topPtr = topPtr->next;
    delete tempPtr;
}
  topPtr = NULL;

}

int Stack::Top() const  // Returns value of top integer on stack WITHOUT modifying the stack
{   
if(!IsEmpty())
return topPtr->data;


throw StackEmpty();
}

int Stack::Size() const // Returns number of items on stack WITHOUT modifying the stack
{

Node* temp = topPtr;
int count = 0;
while (temp != NULL)
{
temp = temp->next;
count ++;
}
return count;

}

int Stack::Max() const  // Returns value of largest integer within stack WITHOUT modifying the stack
                    // If stack is empty, throws StackEmpty
{
int max = 0;
int n;
Node* temp = topPtr;
  if(!IsEmpty())
{
while(temp != NULL)
{
n = temp->data;
if(n > max)
{
max = n;
}
temp = temp->next;
}
return max;}

else 
throw StackEmpty();
}

int Stack::Min() const  // Returns value of smallest integer within stack WITHOUT modifying the stack
                    // If stack is empty, throws StackEmpty
{int min = 100;
int n;
Node* temp = topPtr;
  if(!IsEmpty())
{
while(temp != NULL)
{
n = temp->data;
if(n < min)
{
min = n;
}
temp = temp->next;
}
return min;}

else 
throw StackEmpty();
}

int Stack::Peek(int n) const    // Returns stack value n levels down from top of stack.     Peek(0) = Top()
                            // If position n does not exist, throws StackInvalidPeek
{

int num = 0;
int x = 0;
Node* temp = topPtr;
   if(!IsEmpty())
{
while(temp != NULL)
{

if (x >= n || temp->next == NULL)
 break;
 temp = temp->next;

x++;
}
if (n <= x)
{
num = temp->data;
}
else throw StackInvalidPeek();

}
else
throw StackInvalidPeek();
return num;
}

1 个答案:

答案 0 :(得分:1)

简单。

while (temp != NULL)
{
  cout << temp->data << " ";  
  temp = temp->previous;
}

从您的问题描述和错误代码中,我认为temp->previous不正确。我假设这是在某种push函数中设置的。

void Stack::Push(int n) // Pushes integer n onto top of stack.  
                // If unable to push, throws StackFull exception.
{
  if(!IsFull())
  {
    Node* tempPtr = new Node;
    tempPtr->data = n;
    tempPtr->next = topPtr;
    topPtr = tempPtr;    
  } else
    throw IsFull();
}

你永远不会设置previous,因此它会留下一些未指定的值(零)。此外,您的cpp文件中未设置或检查任何位置 previous。它应该在这里设置,虽然实际上不需要在其他任何地方。

最后,throw IsFull()是一个例外。您可能并不是指throw函数调用的bool结果。