not reading plus sign from stringstream

Hi guys,

I am making a simple program to calculate the y value given x of a expression(y)

anyway it seems like when I enter 5 x + 5 in as my y value it does not read the '+' sign,any ideas why?

thanks



enter equation for y
for example - y = 5x + 5
5 x + 5
enter number for x
7
parser 5 x + 5
TEMP = 5
5 IS DIGIT
TEMP = x
adding x
TEMP = 5
5 IS DIGIT



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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <iostream>
#include <sstream>

using namespace std;


int parse(int x,string& y){

   stringstream parser;

   char temp;
   int num[10];
   char sign[10];
   int digitInc = 0;
   int signInc = 0;
   int numOfDigits = 0;
   int result;

   parser << y;

   cout << "parser " << parser.str() << endl;

   while(!parser.eof()){

      parser >> temp;

      cout << "TEMP = " << temp << endl;

      if(isdigit(temp)){

          parser.putback(temp);
          parser >> num[digitInc];
          digitInc++;
          numOfDigits++;
          cout << temp << " IS DIGIT" << endl;
          continue;
      }

      switch(temp){

   case '+':
        cout << "adding plus" << endl;
        parser >> sign[signInc];
        break;
   case '-':
        parser >> sign[signInc];
        break;
   case '*':
        parser >> sign[signInc];
        break;
   case '/':
        parser >> sign[signInc];
        break;
   case 'x':
       cout << "adding x" << endl;
        parser >> sign[signInc];
        break;

      }
      signInc++;
   }

   result = num[0];
   int j = 0;

   for(int i = 1; i < numOfDigits; i++){

       char signTemp = sign[j];
       j++;

       switch(signTemp){

      case '+':
        result += num[i];
        break;
      case '-':
        result -= num[i];
        break;
      case '*':
        result *= num[i];
        break;
      case '/':
        result /= num[i];
        break;
      case 'x':
        result *= x;
        break;

       }
   }

   return result;
}


int input(){

  int x;
  string y;
  cout << "enter equation for y " << endl;
  cout << "for example - y = 5x + 5" << endl;
  getline(cin,y);


  cout << "enter number for x" << endl;
  cin >> x;

  int result = parse(x,y);

}


int main()
{
    input();
    return 0;
}
*Ok I see where my problem was

I was reading from the stringstream twice once for temp then again in the switch,



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

 switch(temp){

   case '+':
        cout << "adding plus" << endl;
        sign[signInc] = temp;
        break;
   case '-':
        sign[signInc] = temp;
        break;
   case '*':
        sign[signInc] = temp;
        break;
   case '/':
        sign[signInc] = temp;
        break;
   case 'x':
       cout << "adding x" << endl;
        sign[signInc] = temp;
        break;

      }
      signInc++;
   }

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 <sstream>

using namespace std;


int getNumber(stringstream& parser,int& number){

      char temp;
      parser >> temp;

      if(isdigit(temp)){

          parser.putback(temp);
          parser >> number;
          
          return number;
      }

      return -1;
}

int parse(int x,string& y){

   stringstream parser;

   char temp;
   int number;
   int result;

   parser << y;

   cout << "parser value = " << parser.str() << endl;
   result = getNumber(parser,number);

   while(!parser.eof()){

      parser >> temp;

      switch(temp){

   case '+':
        getNumber(parser,number);
        result+=number;
        break;
   case '-':
        getNumber(parser,number);
        result-=number;
        break;
   case '*':
        getNumber(parser,number);
        result*=number;
        break;
   case '/':
        getNumber(parser,number);
        result /= number;
        break;
   case 'x':
        result *= x;
        break;

      }

   }

   cout << "RESULT = " << result << endl;

   return result;
}


int input(){

  int x;
  string y;
  cout << "enter equation for y " << endl;
  cout << "for example - y = 5x + 5" << endl;
  getline(cin,y);


  cout << "enter number for x" << endl;
  cin >> x;

  int result = parse(x,y);

}


int main()
{
    input();
    return 0;
}


ok so finished program above,I think i will also need to implement a format checking function to make sure the format is correct before proceeding with the parsing and calculation,

any tips on how I can improve it are more than welcome :)
What happens if the user enters something like "-y=5x+5" (note the lack of any spaces)? Does it still work as expected?


Last edited on
hi jlb,

lack of spaces seems to work so 5x+5 will give the same result as 5 x + 5
What is the result?

And does the "result" produced agree with your manual computations?

What is the purpose of "result"?

What I got from running the program didn't make much sense to me.






What is the result?

And does the "result" produced agree with your manual computations?




seems to be for example I try sub 0 in for x, and use the equation y = 5x + 5 and I get 5 which is the correct answer

also tried 10x - 5 - 1 subbed 0 in for x again and got 4 which is the correct answer



What is the purpose of "result"?



bad naming convention I think I should have named result y



What I got from running the program didn't make much sense to me.


really what did you get?




enter equation for y
for example - y = 5x + 5
20x - 2
enter number for x
2
parser value = 20x - 2
RESULT = 38



seems to be giving the correct results for me so far
Last edited on


enter equation for y
for example - y = 5x + 5
2x + 5x + 3
enter number for x
2
parser value = 2x + 5x + 3
Y Value = 21



now I get what you mean ^^,reason being the program doesn't know the rules of arithmetic(multiplication before addition) so what it is really doing is 2 by 2 = 4 + 5 = 9 * 2 = 18 + 3 = 21

back to the drawing board.
also tried 10x - 5 - 1 subbed 0 in for x again and got 4 which is the correct answer


I'm not sure how you got 4 being the correct answer here. Even with a strange order of operations, you should still get -6. Did your program read '-' and interpret it as '+'? Or did you possibly mistype your example when you posted?
sorry Doug made a crucial typo there meant to say 10x + 5 - 1 gave me 4

I added a function to check if a value has an x after it but now my while seems to be stuck in an infinite loop,I added a debug statement that printed temp and '+' keeps on being printed so it is obviously not reading any more characters after '+' or keeps on reading the same '+'

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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

#include <iostream>
#include <sstream>

using namespace std;


int getNumber(stringstream& parser,int& number){

      char temp;
      parser >> temp;

      if(isdigit(temp)){

          parser.putback(temp);
          parser >> number;

          return number;
      }

      return -1;
}

bool hasX(stringstream& parser){

    char temp;

    parser >> temp;

    if(temp == 'x'){

        parser.putback(temp);
        return true;

    }else{

     parser.putback(temp);
     return false;

    }
}


int parse(int x,string& y){

   stringstream parser;

   char temp;
   int number;
   int yValue;

   parser << y;

   cout << "parser value = " << parser.str() << endl;
   yValue = getNumber(parser,number);

   while(!parser.eof()){

      parser >> temp;
      cout << temp << endl;

      switch(temp){

   case '+':
        getNumber(parser,number);
        if(hasX(parser)){


          parser >> temp;

          number *= x;
          yValue += number;

        }else{

        yValue+=number;
        }
        break;
   case '-':
        getNumber(parser,number);
        yValue-=number;
        break;
   case '*':
        getNumber(parser,number);
        yValue*=number;
        break;
   case '/':
        getNumber(parser,number);
        yValue /= number;
        break;
   case 'x':
        yValue *= x;
        break;

      }

   }

   cout << "Y Value = " << yValue << endl;

   return yValue;
}


int input(){

  int x;
  string y;
  cout << "enter equation for y " << endl;
  cout << "for example - y = 5x + 5" << endl;
  getline(cin,y);


  cout << "enter number for x" << endl;
  cin >> x;

  int result = parse(x,y);

}


int main()
{
    input();
    return 0;
}

Last edited on
So to answer my own question the reason why I was stuck in an infinite loop was because of my hasX function I was putting a value back into the empty stream the only strange thing is that temp was always the value 'x'

so here is the updated code (which works so far,does multiplication before addition and subtraction,still need to add in division before addition and subtraction)

only problem is this code is very buggy as my hasX function will check the stream to see if the next value is 'x' but when the stream is empty it is checking the memory address past the stream which contains a junk value first time it was '(' on the next execution it was '!',so does the stringstream have a hasNext() function to check if the stream has another character?

(if that junk value just by coincidence turned out to be 'x' it would essentially break my program)

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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

#include <iostream>
#include <sstream>

using namespace std;


int getNumber(stringstream& parser,int& number){

      char temp;
      parser >> temp;

      if(isdigit(temp)){

          parser.putback(temp);
          parser >> number;

          return number;
      }

      return -1;
}

bool hasX(stringstream& parser){

    char temp;

    parser >> temp;

    if(temp == 'x'){

        parser.putback(temp);
        return true;

    }else{

     return false;

    }
}


int parse(int x,string& y){

   stringstream parser;

   char temp;
   int number;
   int yValue;

   parser << y;

   cout << "parser value = " << parser.str() << endl;
   yValue = getNumber(parser,number);

   while(!parser.eof()){

      parser >> temp;
      cout << temp << endl;

      switch(temp){

   case '+':
        getNumber(parser,number);
        cout << "NUMBER : " << number << endl;
        if(hasX(parser)){


          parser >> temp;

          number *= x;
          yValue += number;

        }else{

        yValue+=number;
        }
        break;
   case '-':
        getNumber(parser,number);
        yValue-=number;
        break;
   case '*':
        getNumber(parser,number);
        yValue*=number;
        break;
   case '/':
        getNumber(parser,number);
        yValue /= number;
        break;
   case 'x':
        yValue *= x;
        break;

      }

   }

   cout << "Y Value = " << yValue << endl;

   return yValue;
}


int input(){

  int x;
  string y;
  cout << "enter equation for y " << endl;
  cout << "for example - y = 5x + 5" << endl;
  getline(cin,y);


  cout << "enter number for x" << endl;
  cin >> x;

  int yValue = parse(x,y);
}

int main()
{
    input();
    return 0;
}

again the problem with needing a hasNext function,

I cleaned the code up to except the input in different orders but when I enter 2x + 3 +2x it gives me 7

obviously I could check for this condition in the hasX function but it gets messy and doesn't look very elegant.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

bool hasX(stringstream& parser){

    char temp;

    parser >> temp;

    if(temp == 'x'){

        parser.putback(temp);
        return true;

    }else if(temp == '+'){

        parser.putback(temp);
        return false;
    }else{

        return false;

    }
}




enter equation for y
for example - y = 5x + 5
2x + 3 + 2x
enter number for x
2
parser value = 2x + 3 + 2x
ITERATION4
ITERATION7
ITERATION7
ITERATION7
ITERATION7
Y Value = 7



the reason being the hasX function reads the plus sign and since it is a '+' it does not put it back into the stringstream so yeah I need a way to return false if there is no next token in the stream


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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

#include <iostream>
#include <sstream>

using namespace std;


int getNumber(stringstream& parser,int& number){

      char temp;
      parser >> temp;

      if(isdigit(temp)){

          parser.putback(temp);
          parser >> number;

          return number;
      }

      return -1;
}

bool hasX(stringstream& parser){

    char temp;

    parser >> temp;

    if(temp == 'x'){

        parser.putback(temp);
        return true;

    }else{

     return false;

    }
}


int parse(int x,string& y){

   stringstream parser;

   char temp;
   int number;
   int yValue;
   bool firstTime = true;

   parser << y;

   cout << "parser value = " << parser.str() << endl;
   yValue = getNumber(parser,number);

   while(!parser.eof()){

      parser >> temp;

      switch(temp){

   case '+':
        getNumber(parser,number);
        firstTime = false;

        if(hasX(parser)){


          parser >> temp;

          number *= x;
          yValue += number;

        }else{

        yValue+=number;
        }
        break;
   case '-':
        getNumber(parser,number);
        yValue-=number;
        break;
   case '*':
        getNumber(parser,number);
        yValue*=number;
        break;
   case '/':
        getNumber(parser,number);
        yValue /= number;
        break;
   case 'x':
        if(firstTime){
        yValue *= x;
        firstTime = false;
        }
        break;

      }

      cout << "ITERATION" << yValue << endl;

   }

   cout << "Y Value = " << yValue << endl;

   return yValue;
}


int input(){

  int x;
  string y;
  cout << "enter equation for y " << endl;
  cout << "for example - y = 5x + 5" << endl;
  getline(cin,y);


  cout << "enter number for x" << endl;
  cin >> x;

  int yValue = parse(x,y);
}

int main()
{
    input();
    return 0;
}
Last edited on
Topic archived. No new replies allowed.