StreamString Breaking???

Can anyone help me figure our why my stringstrem s and stringstream chunk keep breaking/not working?

I've noticed that s stops working when I try to read the second line. Instead of returning token, it returns blank the second time.
For chunk, it stops working when it reads a stand-alone number. For example, if I feed it this equation: y = 3x + 4, it works fine. But, if I feed it: 4 = 3x - y, it does not correctly update A and B and remain 0. If I feed it y - 4 = 3x, B is read correctly, but A remains as 0.

Do you have any ideas of what could be causing this malfunction in these two strings? I cannot figure out what would make them quit working.

Thanks in advance.

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
  int main()
{
    string line, token;
    stringstream s, chunk;
    bool rightSide = false, slope = true;
    double A=0, B=0, C=0;
    int sign = 1, count = 0;
    double m, b, y, x;
    Point p1;
    Point p2;
    Line one;
    Line two;

    for(int i=0; i < 2; i++){
            line.clear();
            getline(cin, line);
            s.str("");
            s << line;
            cout << s.str() << endl;
            cout << line << endl;


        while(s >> token){
            chunk.str(""); 

            if(token == "="){
                rightSide = true;
            }
            else if(token.find("x") != string::npos){ 
                if(token.size() == 1){
                    A = 1;
                }
                else if(token == "-x"){
                    A = -1;
                }
                else{
                    chunk << token;
                    chunk >> A;
                }
                if(rightSide){
                    A *= -1;
                }

                A *= sign;
                sign *= sign;
            }

            else if(token.find("y") != string::npos){
                if(token.size() == 1){
                    B = 1;
                }
                else if(token == "-y"){
                    B = -1;
                }
                else{
                    chunk << token;
                    chunk >> B;
                }
                if(rightSide){
                    B *= -1;
                }
                B *= sign;
                sign *= sign;
            }
            else if(token == "-"){
                sign = -1;
            }
            else if(token != "+"){
                chunk << token;
                chunk >> C;

                if(!rightSide){
                    C *= -1;
                }
                C *= sign;
                sign *= sign;
            }

        }

        if(B == 0){
            p1 = Point(C, 0);
            p2 = Point(C, 5);
            slope = false;
        }
        else{
            b = C/B;
            m = A/B;
            x = 0;
            y = m*x+b;
            p1 = Point(x, y);
            x = 5;
            y = m*x+b;
            p2 = Point(x, y);
        }
        if(count == 0){
            one = Line(p1, p2);
        }
        else if(count == 1){
            two = Line(p1, p2);
        }
        count++;

    }
return 0;
}
Hello cc1234ssc,

Tried to work with your program, but appears to be missing a header file. It makes it herd to test the program when I can not compile the code.

Andy
Hey there!

Sorry about that. I didn't post it because I didn't think it was necessary as the part I'm talking about doesn't contain the Line or Point class.

This code has the line and point class taken out so it should work for your compiler but it still produces the error I mentioned above.

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
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

int main()
{
    string line, token;
    stringstream s, chunk;
    bool rightSide = false, slope = true;
    double A=0, B=0, C=0;
    int sign = 1;

    for(int i=0; i < 2; i++){
            line.clear();
            getline(cin, line);
            s.str("");
            s << line;
            cout << s.str() << endl;
            cout << line << endl;


        while(s >> token){
            chunk.str(""); //erases the stuff in chunk

            if(token == "="){
                rightSide = true;
            }
            else if(token.find("x") != string::npos){ //finds the x and returns it if there is an x
                if(token.size() == 1){
                    A = 1;
                }
                else if(token == "-x"){
                    A = -1;
                }
                else{
                    chunk << token;
                    chunk >> A;
                }
                if(rightSide){
                    A *= -1;
                }

                A *= sign;
                sign *= sign;
            }

            else if(token.find("y") != string::npos){ //finds the x and returns it if there is an x
                if(token.size() == 1){
                    B = 1;
                }
                else if(token == "-y"){
                    B = -1;
                }
                else{
                    chunk << token;
                    chunk >> B;
                }
                if(rightSide){
                    B *= -1;
                }
                B *= sign;
                sign *= sign;
            }
           
    return 0;
}
Your second code is missing a couple of closing braces and doesn’t compile. How can it give you the same error?

I’ve added a couple of basic struct to your first post to check your original code (at the end of the day it’s the one you want to make work, isn’t it?).
The main proble I see is that you ‘rely’ on the fact that it works, but you don’t check it. That’s the best way i know to injure oneself. When you write any code, you’d better check it continously while you write it.
Let’s take this code and check it:
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
#include <iostream>
#include <sstream>
#include <string>

struct Point {
    double x, y;
    Point() : x { 0.0 }, y { 0.0 } {}
    Point(double x_arg, double y_arg) : x { x_arg }, y { y_arg } {}
};

struct Line {
    Point p1, p2;
    Line() = default;
    Line(Point p1_arg, Point p2_arg) : p1 { p1_arg }, p2 { p2_arg } {}
};

int main()
{
    std::string line, token;
    std::stringstream s, chunk;
    bool rightSide = false, slope = true;
    double A=0, B=0, C=0;
    int sign = 1, count = 0;
    double m, b, y, x;
    Point p1;
    Point p2;
    Line one;
    Line two;

    for(int i=0; i < 2; i++){
        line.clear();
        std::cout << "Please insert an equation: ";
        std::getline(std::cin, line);
        s.str("");
        s << line;
        std::cout << s.str() << '\n' << line << '\n';

        while(s >> token){
            chunk.str(""); 

            if(token == "="){
                rightSide = true;
            }
            else if(token.find("x") != std::string::npos){ 
                if(token.size() == 1){
                    A = 1;
                }
                else if(token == "-x"){
                    A = -1;
                }
                else{
                    chunk << token;
                    chunk >> A;
                }
                if(rightSide){
                    A *= -1;
                }

                A *= sign;
                sign *= sign;
            }

            else if(token.find("y") != std::string::npos){
                if(token.size() == 1){
                    B = 1;
                }
                else if(token == "-y"){
                    B = -1;
                }
                else{
                    chunk << token;
                    chunk >> B;
                }
                if(rightSide){
                    B *= -1;
                }
                B *= sign;
                sign *= sign;
            }
            else if(token == "-"){
                sign = -1;
            }
            else if(token != "+"){
                chunk << token;
                chunk >> C;

                if(!rightSide){
                    C *= -1;
                }
                C *= sign;
                sign *= sign;
            }

        }
        
        // Let's check what happened:
        std::cout << "A: " << A << "; B: " << B << "; C: " << C << '\n';

        if(B == 0){
            p1 = Point(C, 0);
            p2 = Point(C, 5);
            slope = false;
        }
        else{
            b = C/B;
            m = A/B;
            x = 0;
            y = m*x+b;
            p1 = Point(x, y);
            x = 5;
            y = m*x+b;
            p2 = Point(x, y);
        }
        if(count == 0){
            one = Line(p1, p2);
        }
        else if(count == 1){
            two = Line(p1, p2);
        }
        count++;

    }
    return 0;
}

In the above code, the order in which you insert your equations produces different results: that should not happens.
Please insert an equation: y = 3x + 4
y = 3x + 4
y = 3x + 4
A: -3; B: 1; C: 4
Please insert an equation: 4 = 3x -y

4 = 3x -y
A: -3; B: 1; C: 4

There’s an empty line below the second “Please insert an equation”: it means in the second iteration of your for-loop ‘s’ is empty.
To get evidence of it, just insert the same equations in revers order:
Please insert an equation: 4 = 3x - y
4 = 3x - y
4 = 3x - y
A: -0; B: 1; C: -4
Please insert an equation: y = 3x + 4

y = 3x + 4
A: -0; B: 1; C: -4

You can see how the value of ‘A’ adjusts to the input insertion order.

We can infer what you get in the second iteration is *not* the user input: your variables are likely to be keeping the same values from the previous iteration.
If you had declared your variables where you really needed them, instead of declaring them in a bunch at the beginning of the function, you wouldn’t have fallen in this trap.

The compiler also complains about the unused variable “slope”, but at first sight it’s used here:
1
2
3
4
5
if(B == 0){
    p1 = Point(C, 0);
    p2 = Point(C, 5);
    slope = false;
}

That warning really stuns me... It seems there should be some mistake in your code I can’t see...

I’m sorry I’m not coming up with any solution, but I actually dealt with a similar problem a few days ago and... well, I’m too lazy to analyse it again :-P
http://www.cplusplus.com/forum/general/224852/#msg1028532
Hello cc1234ssc,

After working with the program for awhile I had some problems with the string stream not working right. This is what I came up with that seams to work. I added line 90 to see what had changed. I have not tried Enoizat's suggestion yet to see if it works. See if this does what you want:

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 <string>
#include <sstream>
#include <limits>

//using namespace std;

int main()
{
	std::string line, token;
	//stringstream s, chunk;  // <--- I was having a problem with this setup.
	bool rightSide = false, slope = true;
	double A = 0, B = 0, C = 0;
	int sign = 1;

	for (int i = 0; i < 2; i++)
	{
		line.clear();
		std::cout << "\n Enter formuls: ";
		std::getline(std::cin, line);
		std::istringstream s(line);  // <--- Added. It works better for me.
		s.clear();
		//s.str("");  // <--- No longer a need for these two lines.
		//s << line;
		std::cout << "s = " << s.str() << std::endl;
		std::cout << line << std::endl;


		while (s >> token)
		{
			std::istringstream chunk(token);  // <--- Added.
			//chunk.str(""); //erases the stuff in chunk
			std::cout << "\n " << chunk.str() << std::endl;

			if (token == "=")
			{
				rightSide = true;
			}
			else if (token.find("x") != std::string::npos)
			{ //finds the x and returns it if there is an x
				if (token.size() == 1)
				{
					A = 1;
				}
				else if (token == "-x")
				{
					A = -1;
				}
				else
				{
					//chunk << token;  // <--- Done eariler.
					chunk >> A;
				}
				if (rightSide)
				{
					A *= -1;
				}

				A *= sign;
				sign *= sign;
			}

			else if (token.find("y") != std::string::npos)
			{ //finds the x and returns it if there is an x
				if (token.size() == 1)
				{
					B = 1;
				}
				else if (token == "-y")
				{
					B = -1;
				}
				else
				{
					//chunk << token;  // <--- Done eariler.
					chunk >> B;
				}

				if (rightSide)
				{
					B *= -1;
				}

				B *= sign;
				sign *= sign;
			}

		}  // end while

		std::cout << "\n\n A = " << A << "\n B = " << B << "\n C = " << C << std::endl;  // <---Added.
	}  // end for

	std::cin.get();

	return 0;
}


Hope that helps,

Andy
Topic archived. No new replies allowed.