#include <iostream>
#include <vector>
#include <string>
#include <stdexcept>
#include <fstream>
#include <stack>
usingnamespace std;
int pop(vector<int>& stk);
ifstream indata;
int main() {
indata.open("testfile.txt"); //opens the test file
if (!indata) {
cerr << "Unable to open file testfile.txt"; //check to see if testfile.txt was found
}
vector<int> Stack;
string input; // to read number or operator
while (!indata.eof()) {
indata>>input;
if (isdigit(input[0])) { // if first is digit, it's number.
Stack.push_back(atoi(input.c_str())); // convert, push
} else { // If it's not a number, assume it's an operator
int first, second;
switch (input[0]) {
case'+': Stack.push_back(pop(Stack) + pop(Stack));
break;
case'-': second = pop(Stack);
first = pop(Stack);
Stack.push_back(first - second);
break;
case'*': Stack.push_back(pop(Stack) * pop(Stack));
break;
case'/': second = pop(Stack);
first = pop(Stack);
Stack.push_back(first/ second);
break;
case'.' :
cout << "Result: " << Stack.back() << endl;
break;
default: throw domain_error("Undefined operator");
}
}
} return 0;
}
int pop(vector<int>& stk) {
if (stk.empty()) {
throw underflow_error("Stack underflow.");
}
int result = stk.back();
stk.pop_back();
return result;
}
right now there is a '.' in place of what i need in the final case statement to show what my goal is. However the periods cannot be in the text document.
any ideas? someone said i could maybe use ascii for end line? but i have no idea how to do that..
There might be an ascii code for EOF (the ascii code for null is '\0'). Check somewhere, I can't say for sure.
I hope you mean EOL :-D. Anyway, the ascii is usually either \n (linux) or \r (mac) or \r\n (windows. two characters)
But... it will be consumed silently by istream::operator>> in line 25. You won't get to know the line end with this construction.
What you can do is use istream::getline instead, which reads a whole line so you know for sure that the just-read line ends at the end of .. the line. ;)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
while (indata)
{
string line;
indata.getline(line);
// now process all token in "line"
stringstream in_line(line);
while (in_line)
{
string input; in_line >> input;
...
}
cout << "Result: " << Stack.back() << endl;
}
hmm that looks promising!=] ive never used stringstream before though.. basically youre reading from in_line just like you would a .txt document if im understanding this correctly? so you store the first line of data into line. then read from it using in_line>>input, storing the data you read into input. is that right?
so i took your advice with the streamstring and have gotten it to work for the most part, however it gets stuck in the while (ss) loop, line 54.
any idea why?
#include <iostream>
#include <vector>
#include <string>
#include <stdexcept>
#include <fstream>
#include <stack>
#include <sstream>
usingnamespace std;
int pop(vector<int>& stk);
ifstream indata;
/*
void readdata () {
while (indata)
{
string line;
getline(indata, line);
// now process all token in "line"
std::stringstream ss(line);
while (ss)
{
string input;
ss>> input;
}
}}
*/
int main() {
indata.open("testfile.txt"); //opens the test file
if (!indata) {
cerr << "Unable to open file testfile.txt"; //check to see if testfile.txt was found
}
vector<int> Stack;
string input; // to read number or operator
while (!indata.eof()) {
string line;
getline(indata, line);
// now process all token in "line"
std::stringstream ss(line);
while (ss) {
ss>> input;
// indata>>input;
if (isdigit(input[0])) { // if first is digit, it's number.
Stack.push_back(atoi(input.c_str())); // convert, push
} else { // If it's not a number, assume it's an operator
int first, second;
switch (input[0]) {
case'+': Stack.push_back(pop(Stack) + pop(Stack));
break;
case'-': second = pop(Stack);
first = pop(Stack);
Stack.push_back(first - second);
break;
case'*': Stack.push_back(pop(Stack) * pop(Stack));
break;
case'/': second = pop(Stack);
first = pop(Stack);
Stack.push_back(first/ second);
break;
// case '\n' :
break;
default: throw domain_error("Undefined operator");
}}
// }cout<<5;
cout << "Result: " << Stack.back() << endl;
} return 0;
}
int pop(vector<int>& stk) {
if (stk.empty()) {
throw underflow_error("Stack underflow.");
}
int result = stk.back();
stk.pop_back();
return result;
}
Huh? You too? Some other guy around the forum got also problems with the "operator void*()" on stringstream. What's up with this? maybe a quirk in the implementation.
Whatever, try "while(!ss.eof())" instead, which is almost the same.