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? 1234567890the 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

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.
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?
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.
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 entriesIn 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);
}
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.
