Can anyone help with my logic?

October 22, 2010 at 13:04:20
Specs: Windows 7
I have been trying so many different things trying to get my program to run properly! It's an RPN Calculator that gets its input from an input file. Finally got rid of all my errors but now I'm just getting output waaaay too far off. Someone please lean me in the right direction at least?

Here is the cpp file:

#include <cctype>           // using isdigit()
#include <climits>          // using INT_MIN
#include <fstream>          // using ifstream
#include <iostream>         // for console io
#include "myStack.h"
using namespace std;

void arithmetic(const char &, myStack <int> &);   //basic operations (+ - * /)
void equals(myStack <int> &);                     //finish up
void error(char *, myStack <int> &);              //send err msg; clear stack
void max(myStack <int> &);                        //find max of x values (^)
void neg(myStack <int> &);                        //negate x (!)
void number(char &, ifstream &, myStack <int> &); //read in a number

//=============================================================================
int main() {
    char ch;
	ifstream fin;
	myStack<int> stack;
    stack.initializeStack();

	fin.open("infile.txt");
	if(!fin) {
        cerr << "\"infile.txt\" does not exist.\nPress a key to exit... ";
        cin.get();
        return -1;
    }
//-----------------------------------------------------------------------------
    while( (ch = fin.get()) != EOF ) {
        if( isdigit(ch) )   number(ch, fin, stack);           // get the number
        if( ch == EOF) break; // Just in case ch scanned in by number() was EOF
        switch (ch) {
            case ' '  :
            case '\f' :
            case '\n' :
            case '\r' :
            case '\t' :
            case '\v' : break;                            // ignore white space
            case '+'  :
            case '-'  :
            case '*'  :
            case '/'  : arithmetic(ch, stack); break;     // perform arithmetic
            case '^'  : max(stack);            break;     // find maximum
            case '!'  : neg(stack);            break;     // negate x
            case '='  : {                                 // equals sign
                equals(stack);
                while(fin.get() != '\n'); // clear to end of line
                break;
            }
            default   : {                                 // invalid operator
                cout << ch << " is not a valid operator.\n";
                stack.initializeStack();
                while(fin.get() != '\n'); // clear to end of line
                break;
            }
        }
    } // end while((ch = fin.get()) != EOF)
//-----------------------------------------------------------------------------
    fin.close();
    cout << "\nAll done. Bye bye!";
    cin.sync();
    cin.get();
    return 0;
} // end main()

//== DO NOT CHANGE ANYTHING ABOVE. YOU MAY BREAK SOMETHING! ===================

//== DO COMPLETE THE FUNCTIONS BELOW. BLANK LINES SHOW SIZE OF ORIGINAL CODE.
//=============================================================================
void arithmetic(const char &ch, myStack <int> &stack) {        // + - * and /
    int x, y, result;

    cout << ch << " ";
    x = stack.top();
    stack.pop();
    y = stack.top();
    stack.pop();
    if(ch == '+') {
    result = x + y; stack.push(result);
    } else if(ch == '-') {
    result = x - y; stack.push(result);
    } else if(ch == '*') {
    result = x * y; stack.push(result);
    } else if(ch == '/'){
    result = x / y; stack.push(result);
    } else {cout << x << " " << y << " " << ch << " ARITHMETIC ERROR.";}
}

//=============================================================================
void equals(myStack <int> &stack) {            // display result; clear stack
    int x;

    cout << "= ";
    x = stack.top();
    stack.pop();
    if(stack.isEmpty() == false) {
    cout << "Stack is not empty. Expression may have been entered incorrectly."; stack.initializeStack();
    } else { 
    cout << x; stack.initializeStack();}   
}

//=============================================================================
void error(char *msg, myStack <int> &stack) {   // display error; clear stack
    cout << msg << "An error has occured.\n";
    stack.initializeStack();
}

//=============================================================================
void max(myStack <int> &stack) {                  // find maximum of x values
    int i, x, maximum = INT_MIN, value;

    cout << "^ ";
    while(stack.isEmpty() == false) {
    i = stack.top();
    stack.pop();
    x = stack.top();
    stack.pop();
    if(i > x){i = value;} else {x = value;}
    if(value > maximum)
    {maximum = value;} else {
    maximum = maximum;}
    }
    stack.push(maximum);
    cout << stack.top();
}

//=============================================================================
void neg(myStack <int> &stack) {                  // negate the x stack value
    int x;
    
    cout << "! ";
    x = stack.top();
    x = -x;
    stack.pop();
    stack.push(x);
}
//=============================================================================
void number(char &ch, ifstream &fin, myStack <int> &stack) { // input integer
    int num = (int)(ch - '0');
  /*  char i = 0;
    
    char array[i];
    stack.initializeStack();
    while( (ch = fin.get()) != EOF ) {
    num = fin.get();       // get character from file
    if (fin.good())
    stack.push(num);
    cout << num;
    }
     
    fin.close();*/





}

I'm not too worried about the last function at this point.


And the input file:

11   21  + =                                Everything after = is ignored.
200  100 - =                                Testing minus.
10 100 * =                                  Testing multiply.
64  32  /  =                                Testing divide.

12 24 18 3 ^ =                              Testing maximum.
100  11  ! + =                              Testing negation.

10 10 + 5 - 3 / =                           Testing multiple operations.
1 2 3 4 5 6 7 8 9 10 + + + + + + + + + =    Testing multiple operations.

10 5 /
3 *
4 +
!
20 -
31 +
=                                           It works across multiple lines.

100  11  $ =                                Testing illegal operator.
2 2 + =                                     Does calculator recover?

10 * =                                      Testing insufficient arguments.
2 2 + =                                     Again, does calculator still work?
1234567890

the arithmetic expressions are supposed to store all of the numbers sequentially into a stack until it detects an operator. then when said operator is detected it jumps into Arithmetic() passing the appropriate character to perform the operation. but the output i end up getting is the first number on every line showing the "is not a valid operator" error up until my negate statement which just shows "!" then crashes. PLEASE help!

edited by moderator: Added PRE tags. -Razor2.3


See More: Can anyone help with my logic?

Report •


#1
October 22, 2010 at 14:17:26
Disclaimer: I don't have access to your "myStack.h", so I substituted it with
#include <stack>
#define myStack             stack
#define initializeStack()     empty()
#define isEmpty()             empty()
So any answer I provide is biased off of STL's stack template.

It looks like the main loop is expecting number() to parse all digits on the line, and fill ch with the first non-whitespace, non-digit value. As to why it crashes, that's because neg is trying to read from an empty stack.

How To Ask Questions The Smart Way


Report •

#2
October 22, 2010 at 15:53:28
Oh WOW lol thought that function was for something completely different, thank you! Only problem now is telling it which integers to combine into one number and which ones are for separate numbers on the same line :S Tried a character array to a string but either way as far as I can tell there is no way for the numbers() function to tell when there is a space or delimiter?

Report •

#3
October 22, 2010 at 16:02:23
If the writer of the main() function was nice, he'd use istream.peek() instead of istream.get(), so you could just use istream.operator<<(). He didn't, though, so you'll need to take the successive digits and combine them into a single number, while ignoring whitespace.

Really, the entire main loop should be rewritten, but I guess that comes in the next class.

How To Ask Questions The Smart Way


Report •

Related Solutions

#4
October 24, 2010 at 13:35:33
Well I have managed to make some headway, but now I have everything compiled and am still getting the same error as before? just comes up with the fist number of every line followed by " is not a valid operator". it seems like its not even detecing the numbers as digits and as a result never even calls the number() function. and I can't change main -.-" heres the new code:

/* rpnCalc.cpp
An RPN calculator to exercise the stack.h implementation.
The calculator works with integers only.
The stack's top value is known as x; the second from top is called y.

The operators are + - * / ! ^ and =
! means to negate the top value (i.e., x becomes -x)
^ takes the top value (x) and uses that to find
the maximum of the next x stack entries

In order to simplify testing, input is taken from a text file
in the same directory as the executable. File name is infile.txt.
Any line text after the = sign is ignored.

Originally prepared by Marty Boogaart 26 September 2007.

Special "STRIPPED DOWN" version for student assignment.
Prepared by Marty Boogaart 19 October 2008.
*/

#include <cctype> // using isdigit()
#include <climits> // using INT_MIN
#include <fstream> // using ifstream
#include <iostream> // for console io
#include "myStack.h"
using namespace std;

void arithmetic(const char &, myStack <int> &); //basic operations (+ - * /)
void equals(myStack <int> &); //finish up
void error(char *, myStack <int> &); //send err msg; clear stack
void max(myStack <int> &); //find max of x values (^)
void neg(myStack <int> &); //negate x (!)
void number(char &, ifstream &, myStack <int> &); //read in a number

//=============================================================================
int main() {
char ch;
ifstream fin;
myStack<int> stack;
stack.initializeStack();

fin.open("infile.txt");
if(!fin) {
cerr << "\"infile.txt\" does not exist.\nPress a key to exit... ";
cin.get();
return -1;
}
//-----------------------------------------------------------------------------
while( (ch = fin.get()) != EOF ) {
if( isdigit(ch) ) number(ch, fin, stack); // get the number
if( ch == EOF) break; // Just in case ch scanned in by number() was EOF
switch (ch) {
case ' ' :
case '\f' :
case '\n' :
case '\r' :
case '\t' :
case '\v' : break; // ignore white space
case '+' :
case '-' :
case '*' :
case '/' : arithmetic(ch, stack); break; // perform arithmetic
case '^' : max(stack); break; // find maximum
case '!' : neg(stack); break; // negate x
case '=' : { // equals sign
equals(stack);
while(fin.get() != '\n'); // clear to end of line
break;
}
default : { // invalid operator
cout << ch << " is not a valid operator.\n";
stack.initializeStack();
while(fin.get() != '\n'); // clear to end of line
break;
}
}
} // end while((ch = fin.get()) != EOF)
//-----------------------------------------------------------------------------
fin.close();
cout << "\nAll done. Bye bye!";
cin.sync();
cin.get();
return 0;
} // end main()

//== DO NOT CHANGE ANYTHING ABOVE. YOU MAY BREAK SOMETHING! ===================

//== DO COMPLETE THE FUNCTIONS BELOW. BLANK LINES SHOW SIZE OF ORIGINAL CODE.
//=============================================================================
void arithmetic(const char &ch, myStack <int> &stack) { // + - * and /
int x, y, result;

cout << ch << " ";
x = stack.top();
stack.pop();
y = stack.top();
stack.pop();
if(ch == '+') {
result = x + y; stack.push(result);
} else if(ch == '-') {
result = x - y; stack.push(result);
} else if(ch == '*') {
result = x * y; stack.push(result);
} else if(ch == '/'){
result = x / y; stack.push(result);
} else {cout << x << " " << y << " " << ch << " ARITHMETIC ERROR.";}
}

//=============================================================================
void equals(myStack <int> &stack) { // display result; clear stack
int x;

cout << "= ";
x = stack.top();
stack.pop();
if(stack.isEmpty() == false) {
cout << "Stack is not empty. Expression may have been entered incorrectly."; stack.initializeStack();
} else {
cout << x; stack.initializeStack();}
}

//=============================================================================
void error(char *msg, myStack <int> &stack) { // display error; clear stack
cout << msg << "An error has occured.\n";
stack.initializeStack();
}

//=============================================================================
void max(myStack <int> &stack) { // find maximum of x values
int i, x, maximum = INT_MIN, value;

cout << "^ ";
while(stack.isEmpty() == false) {
i = stack.top();
stack.pop();
x = stack.top();
stack.pop();
if(i > x){i = value;} else {x = value;}
if(value > maximum)
{maximum = value;} else {
maximum = maximum;}
}
stack.push(maximum);
cout << stack.top();
}

//=============================================================================
void neg(myStack <int> &stack) { // negate the x stack value
int x;

cout << "! ";
x = stack.top();
x = -x;
if(stack.isEmpty() == false) {stack.pop(); stack.push(x);}
else {stack.push(x);}
}
//=============================================================================
void number(char &ch, ifstream &fin, myStack <int> &stack) { // input integer
int num = (int)(ch - '0');
int i = 0;
char nextNum;

for(i=0;i<=10;i++) {
if(isdigit(fin.get())) {
nextNum = fin.get();
num = num + nextNum;
} else { break; }
}

stack.push(num);


}



Report •

#5
October 24, 2010 at 15:38:51
Your void number() will pretty much need to be scratched and re-thought. It doesn't compute the numbers correctly, it skips every other character, it doesn't fill ch with the relevant character, it doesn't handle whitespace, it doesn't handle an unexpected EOF, and it'll terminate after pulling 20 characters off the ifstream.

How To Ask Questions The Smart Way


Report •


Ask Question