Why is this loop infinite?

Shouldn't this program stop, and ask me to "Enter number of values you want to sum: " again, after the first run? Without the while loop, the code does what it is supposed to. Code starts infinite loop after values.push_back(val); part at line 27.

What is the correct way to get this code to run again without having to restart the 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
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;


vector<int> values;
int sum = 0;

int summer(int num) { // Sum number of values.
    for (int i = 0; i < num; ++i)
        sum += values[i];
        return sum;
    };

int main()
{

    while (1) {

        cout << "Enter number of values you want to sum: ";
        int numofValues = 0;
        cin >> numofValues;

        cout << "Enter some integers. Enter any letter when done: ";
        for (int val; cin >> val;)
            values.push_back(val);

        cout << "\nSum of the first " << numofValues << " numbers is " << summer(numofValues);
        values.clear(); // Clear vector.
    };
}
Last edited on
When an input operation fails, the stream gets set in a bad state. All further input operations will automatically fail.

Please read:
http://www.LB-Stuff.com/user-input
if you put a while(true){} or a for(;;) at least you need a break;
also I dont recommend the condition cin >> val; assign it to a temp variable then do the checking to prevent any runtime failures.
Ericool wrote:
also I dont recommend the condition cin >> val;
Why not? Looping on the input/output operation is generally considered the correct way to handle input/output operations.
@LB

there is 2 loops and no check-value...
Ericool wrote:
there is 2 loops and no check-value...
I don't understand what you mean?
@LB
-2 loops I was referencing to no break
-no check-value : never trust the user to enter the correct type of value , never think a file is not corrupted (mostly for serialization).

From now on , this is ok but you might want to add extra checking to avoid further additionnal - I dont know what is going on.
Ericool wrote:
-no check-value : never trust the user to enter the correct type of value , never think a file is not corrupted (mostly for serialization).
Using the input operation as the condition is the way you deal with this. Please read:
http://www.LB-Stuff.com/user-input
Can I enter all input with functions like this or is there going to be problems?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int integer () {
std::string line;
int num;

while (std::getline(std::cin, line)
&& !(std::istringstream{line} >> num))
{std::cout << "invalid input\n";};
std::istringstream {line} >> num;
return num;
};

int main ()
{
	int a = integer ();
	int b = integer ();
	std::cout << a+b;
}
You seem to have accidentally changed the order of conditions/statements and your code no longer does the right thing. Re-read my article's code more closely. You can definitely use functions, just make sure you understand what the code actually does.
@vjaako: why you returning num while you have submit its value with stringstream?
@chipp: it's hard to tell from the poor indentation, but that's actually inside a function, so it's fine.
@chipp: What do you mean?

Updated code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int numint () { //Read in integer
std::string line;
int num;

while (std::getline(std::cin, line)) {
std::istringstream is {line} ;
if ((is >> num) && !(is >> line)) {
        return num;
	break; };
	std::cout << "invalid input, try again.\n"; };
};

int main ()
{
	int a = numint ();
	int b = numint ();
	std::cout << a+b << std::endl;
}

That's better. The break on line 9 is superfluous - you're returning from the function before that so no code after that will run. Also, your indentation style makes it really hard to read your code, try it this way instead:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int numint()
{   //Read in integer
    std::string line;
    int num;
    while(std::getline(std::cin, line))
    {
        std::istringstream is {line};
        if((is >> num) && !(is >> line))
        {
            return num;
        }
        std::cout << "invalid input, try again.\n";
    }
}

int main()
{
	int a = numint ();
	int b = numint ();
	std::cout << a+b << std::endl;
}
Why do you put semicolons after closing braces? That's not necessary.
Last edited on
@OP: oic... i thought it was from inside while loop, not from a function. LB indentation is better. easier to read. less misunderstandings.
Topic archived. No new replies allowed.