CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Feb 2012
    Posts
    23

    [RESOLVED] Problem with passing a stack by reference

    I'm having trouble using a stack's functions when passing it by reference.
    I'm currently messing around with passing a pointer to the stack instead, but to no avail.
    Any help would be appreciated. The problem is in my placeInto function. I will label, in my code, where the program stops.

    Code:
    /*
    This code was created by Brandon *****.
    The program is an RPN Calculator, designed to recieve keyboard input of an infix mathematical string, convert
    the infix string into a postfix mathematical string, and then solve the string. The program then outputs the
    postfix string and the solution.
    The program loops through until closed via force-close, as was assigned.
    */
    
    #include <iostream>
    #include <string>
    #include <stack>
    using namespace std;
      
     ///////////////////////
    // function prototypes //
     ///////////////////////
    
    // u = unfinished
    /*  1*/void welcome(); // welcome screen
    /*  2*/bool input(); // prompt for input (infix string). If returns false, invalid input. (only numbers, parens, spaces, and - + * / allowed.)
    /*  3*/void convert(); // convert infix string to postfix string
    /*  4*/int  solve(); // solve the postfix string. This is used in (5)output().
    /*  5*/void output(); // output the postfix string and the result. The result is calculated in output() via (4)solve().
    /*  6*/void reset(); // reset global values to NULL
    /*  7*/bool isValid(char); // used in (2)input() to check for iChar's validity. If returns false, (2)input() also returns false.
    /*  8*/void invalidInput(); // used if (2)input() returned false. Explains to the user: try again.
    /*  9*/bool isDigit(char); // used in (3)convert() to determine whether inString[i] is a digit. Returns true: is a digit.
    /* 10*/bool isOperand(char); // used in (3)convert() to determine whether inString[i] is an operand. Returns true: is an operand.
    /* 11*/void unStack(stack<char> &, int &); // used in (3)convert() to "unstack" (remove all operators from a stack and append them to global-postString). Needs to increment postCount with each append.
    /* 12*/void placeInto(stack<char> &, char, int &); // used in (3)convert() to correctly push an item into a select stack. (cannot have <operands in the stack ontop of >operands)
    /* 13*/int  opValue(char); // return a value for a char operator. values: -(1) +(2) *(3) /(4).. used in (4)solve()
    /* 14*/int  toNum(char); // take in a char digit, spit out the cooresponding decimal digit.. used in (4)solve()
    
    /* Notes
    /* u = unsolved
    /* s = solved
    /u/ Referring to parenStack in (3)convert(): need to make more dimensions of inParens (which means more parenStack's).
        If possible, would be nice to: stack<char> parenStack[5]; and turn inParens into an int,
        the value of which would pertain to the current dimension of parenStack.
    /u/ Referring to the usage of solve() in (5)output(): might be unable to cout << solve(); 
        if so, int result = solve(); cout << result;
    */
    
     ////////////////////
    // global variables //
     ////////////////////
    
    char
        inString[100] = {NULL}, //infix string, contains no spaces.
        postString[100] = {NULL}; //postfix string, converted from infix string in (3)convert().
    
    
     ////////////////////
    // main() ////////////
    
    int main()                                  
    {                                            
        welcome();                           
        while(1 < 2)                            
        {                                       
            if(input())                   
            {                                   
                cout << "Before convert()" << endl;
                convert();
                cout << "Before output()" << endl;                
                output();            
            }                                    
            else                               
                invalidInput();           
            
            cout << "Before reset()" << endl;                                         
            reset();                                      
        }                                                 
        return 0;                                          
    }        
                                                  
    // End of main() /////
     ////////////////////
    
    
     ////////////////////////
    // Function definitions //
     ////////////////////////
     
    /* 1*/void welcome()
    {
         cout << "Welcome to Brandon's RPN Calculator!" << endl
              << "Input an infix mathematical string to have it converted to RPN and solved!" << endl
              << "Valid characters: single digits - + * / ) ( and space" << endl
              << endl
              << "Press ctrl-c at any time to exit." << endl
              << endl;
              
              system("PAUSE");
              system("CLS");
    }
    
    /* 2*/bool input()
    {
           char tempString[250] = {NULL};
           int inCount = 0;
           
           cout << "Input your infix string:" << endl
                << "? ";
           cin.getline(tempString, 250);
           for(int i = 0; (tempString[i] != NULL); i++)
           {
                 if(!isValid(tempString[i]))
                      return false;
                      
                 if(tempString[i] != ' ')
                 {
                      inString[inCount] = tempString[i];
                      inCount++;
                 }
           }
           return true;
    }
    
    /* 3*/void convert()
    {
    int isDigits = 0;
         int 
             postCount = 0;
         bool
             inParens = false;
         stack<char> opStack;
         stack<char> parenStack;
         for(int i = 0; (inString[i] != NULL); i++)
         {
                 if(inString[i] == '(')
                      inParens = true;
                 else
                     if(inString[i] == ')')
                     {
                          inParens = false;
                          unStack(parenStack, postCount);
                     }
                     else
                         if(isOperand(inString[i]))
                         {
                         cout << "isOperand." << endl;
                              if(inParens)
                                   placeInto(parenStack, inString[i], postCount);
                              else
                                   placeInto(opStack, inString[i], postCount);
                                   cout << "isOperand end." << endl;
                         }
                         else
                             if(isDigit(inString[i]))
                             {
                                                     isDigits++;
                             cout << "isDigit. " << isDigits << endl;
                                  postString[postCount] = inString[i];
                                  postCount++;
                             }      
         }
         cout << "before unstack" << endl;
         unStack(opStack, postCount);
         cout << "after unstack" << endl;
    }
    
    /* 4*/int solve()
    {
               stack<char> solveStack;
               int
                  int1,
                  int2;
                  
               for(int i = 0; (postString[i] != NULL); i++)
               {
                       if(isDigit(postString[i]))
                            solveStack.push(toNum(postString[i]));
                       else
                       {
                           int2 = solveStack.top();
                           solveStack.pop();
                           int1 = solveStack.top();
                           solveStack.pop();
                           switch(postString[i])
                           {
                           case '-':
                                if(!solveStack.empty())
                                    solveStack.push(int1 - int2);
                                else
                                    return int1 - int2;
                                break;
                           case '+':
                                if(!solveStack.empty())
                                    solveStack.push(int1 + int2);
                                else
                                    return int1 + int2;
                                break;
                           case '*':
                                if(!solveStack.empty())
                                    solveStack.push(int1 * int2);
                                else
                                    return int1 * int2;
                                break;
                           case '/':
                                if(!solveStack.empty())
                                    solveStack.push(int1 / int2);
                                else
                                    return int1 / int2;
                                break;
                           }
                       }
               }
    }
    
    /* 5*/void output()
    {
               cout << "Postfix String:" << endl 
                    << postString << endl
                    << endl
                    << "Result:" << endl
                    << solve() << endl
                    << endl;
    }
    
    /* 6*/void reset()
    {
         system("PAUSE");
         system("CLS");
         for(int i = 0; (inString[i] != NULL); i++)
                 inString[i] = NULL;
         for(int i = 0; (postString[i] != NULL); i++)
                 postString[i] = NULL;     
    }
    
    /* 7*/bool isValid(char iChar)
    {
         switch(iChar)
         {
         case ' ':
         case '(':
         case ')':
         case '-':
         case '+':
         case '*':
         case '/':
         case '0':
         case '1':
         case '2':
         case '3':
         case '4':
         case '5':
         case '6':
         case '7':
         case '8':
         case '9':
              return true;
         default:
              return false;
         }
    }
    
    /* 8*/void invalidInput()
    {
         cout << "Invalid input detected." << endl
              << "Please input only legal characters:" << endl
              << "single digits - + * / ) ( and space" << endl
              << endl;     
    }
    
    /* 9*/bool isDigit(char iChar)
    {
               switch(iChar)
               {
                    case '0':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                    case '8':
                    case '9':
                         return true;
                    default:
                         return false;
               }
    }
    
    /*10*/bool isOperand(char iChar)
    {
               switch(iChar)
               {
                    case '-':
                    case '+':
                    case '*':
                    case '/':
                         return true;
                    default:
                         return false;
               }
    }
    
    /*11*/void unStack(stack<char> & iStack, int & postCount)
    {
               while(!iStack.empty())
               {
                    postString[postCount] = iStack.top();
                    postCount++;
                    iStack.pop();
               }
    }
    
    /*12*/void placeInto(stack<char> & iStack, char iChar, int & postCount)
    {
               cout << "before while of placeinto" << endl;
               while(opValue(iStack.top()) > opValue(iChar)) //***** The program stops here.
               {
                    cout << "inside while of placeinto" << endl;
                    postString[postCount] = iStack.top();
                    postCount++;
                    iStack.pop();
               }
               cout << "after while of placeinto" << endl;
               iStack.push(iChar);
    }
    
    /*13*/int opValue(char iChar)
    {
              cout << "before switch of opValue" << endl;
              switch(iChar)
              {
              case '-':
                   return 1;
              case '+':
                   return 2;
              case '*':
                   return 3;
              case '/':
                   return 4;
              }
    }
    
    /*14*/int toNum(char iChar)
    {
              return (int)iChar - 48;
    }

  2. #2
    Join Date
    Feb 2012
    Posts
    23

    Cool Re: Problem with passing a stack by reference

    To those who care:
    I finally found the problem. I was calling iStack.top() while iStack was empty.
    To circumvent this, I did:
    Code:
    /*12*/void placeInto(stack<char> & iStack, char iChar, int & postCount)
    {
               if(!iStack.empty())
                   while(opValue(iStack.top()) > opValue(iChar))
                   {
                        postString[postCount] = iStack.top();
                        postCount++;
                        iStack.pop();
                   }
               iStack.push(iChar);
    }

    ...Now to figure out how to get the program to output decimal results instead of rounding down..
    =.=

  3. #3
    Join Date
    Aug 2009
    Posts
    440

    Re: [RESOLVED] Problem with passing a stack by reference

    When you say round down, do you mean truncate? With integer division when you do 5/2, the result is 2. If you want the decimal, then use doubles instead of ints.

  4. #4
    Join Date
    Feb 2012
    Posts
    23

    Re: [RESOLVED] Problem with passing a stack by reference

    Yes, I did mean truncating.
    I switched it to floats and I set the precision to 10.
    The program is working flawlessly now if anyone is interested in seeing the RPN Calculator

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured