making a case for end of line

Heres my code below, i am trying to make a case statement so that when it reads that its at the end of a line, it will print out the answer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>
#include <vector>
#include <string>
#include <stdexcept>
#include <fstream>
#include <stack>
using namespace 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;
}

testfile.txt:
10 12 2 / + 8 3 * - .
10 12 + 2 / 8 3 * - .
10 12 2 8 - / + 3 * .

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.
Why not read an entire line with getline(), then parse the line into tokens with an istringstream?
Either 10 or '\n'. They are equivalent practically everywhere.
i tried case '\n' but it dint work=/ is there a different way i should be writing it?
thanks!
tummychow wrote:
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?

heres the new code. and thanks!


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <iostream>
#include <vector>
#include <string>
#include <stdexcept>
#include <fstream>
#include <stack>
#include <sstream>
using namespace 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.

Ciao, Imi.

try this instead:

54
55
56
while (ss >> input) {
    ...
}


The problem is that at some point 55 fails and you don't know about it until its too late.
The problem is that at some point 55 fails and you don't know about it until its too late.

hm.... damnit, you're right! How stupid of me. I go and tell the other guy... *strolling off*

Ciao, Imi.
Topic archived. No new replies allowed.