Quitting a while() loop with '|' creates infinite loop.

I'd like to start off by telling everyone thank you in advance. I am new to the forum and new to C++. In my spare time, which is sometimes null, I have been working through the book "Programming Principles and Practice Using C++" by Bjarne Stroustrup. In an exercise, he makes a pretty simple request.

"Write a program that consists of a while-loop that reads in two ints and then prints them. Exit the program when a terminating '|' is entered."

Seemed simple enough so i came up with the following code.

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
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;
inline void keep_window_open() { char ch; cin >> ch; }

int main()
{
	int i = 0;
	while (i >= 0)
	{
		int x = 0;
		int y = 0;
		
		cout << "Please enter two integers followed by enter:\n";
		cin >> x >> y;

		if (x == '|' || y == '|')
		{
			return 0;
		}
		else
		{
			cout << "The first number is " << x << " and the second number is " << y << '\n';
		}
	}
	keep_window_open();
	return 0;
}


The program works fine as long as ints are entered. Once the terminating '|' is entered, the program enters an infinite loop where it constantly asks for two ints until i force quit with ctrl-c. I don't understand why it reacts this way. The code seems simple enough, but reacts oddly when run. Does anyone see why this program would loop the way it does?
closed account (E0p9LyTq)
'|' is a char, not an int. You need to compare int to int:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>

int main()
{
   while (true)
   {
      int x = 0;
      int y = 0;

      std::cout << "Please enter two integers followed by enter (-1 to quit): ";
      std::cin >> x >> y;

      if (x == -1 || y == -1)
      {
         break;
      }

      std::cout << "The first number is " << x << " and the second number is " << y << '\n';
   }
}

Please enter two integers followed by enter (-1 to quit): 3
5
The first number is 3 and the second number is 5
Please enter two integers followed by enter (-1 to quit): -1
-1

Last edited on
Interesting. I was under the impression that if a char was entered and read into an int that it would be converted by the compiler to numerical value. If I stay with the books request of using a '|' as the quit character, then i need some way for the program to recognize that as a quit character. This is where i am stuck. I do like the while (true). Much simpler than creating a loop variable for something i don't need to count the loops. Also, break instead of return 0 makes much more sense.
I don't know which of Stroustrup's exercises this is referring to, but the wording of it sounds quite weird. Honestly, a lot of that book is kinda weird.

To be able to input and parse both multi-digit numbers and characters like '|', you need to first make the input be of the "lowest common denominator", which in this case could be std::string.

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

using std::cin;
using std::cout;

inline void keep_window_open() { char ch; cin >> ch; }

int main()
{
	while (true)
	{
		std::string x_str;
		std::string y_str;
		
		cout << "Please enter two integers followed by enter:\n";
		cin >> x_str >> y_str;
		
		std::stringstream ss_x(x_str);
		std::stringstream ss_y(y_str);
		
		int x;
		int y;

		if (x_str == "|" || y_str == "|")
		{
			cout << "Goodbye.\n";
			break;
		}
		else if (!cin || !(ss_x >> x) || !(ss_y >> y))
		{
			cout << "Bad input!\n";
			cin.clear();
			cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
		}
		else
		{
			cout << "The first number is " << x << " and the second number is " << y << '\n';
		}
	}
	keep_window_open();
	return 0;
}
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
#include <iostream>
#include <sstream>
#include <string>
using namespace std;

int main()
{
   const char END = '|';
   int a, b;
   char c;
   string line;

   while( true )
   {
      cout << "Enter two integers on one line (or " << END << " to terminate): ";
      getline( cin, line );
      if ( stringstream( line ) >> a >> b )                          // If successfully read integers
      {
         cout << "You entered " << a << " and " << b << '\n';
      }
      else if ( stringstream( line ) >> c && c == END )              // The first char read is the end sentinel
      {
         cout << "You entered " << END << " and this program is now terminating\n";
         return 0;
      }
      else                                                           // Can't figure it out
      {
         cout << "Whatever you said is wrong (quoting my children!)\n";
      }
   }
}
I appreciate the responses. It looks like stringstream is the solution to my problem. Whats interesting is that you said that this book is weird. It is. This is the second time in four chapters that the solution to the problem he presents is found further in the book. I will look into that function to understand better how it works.
Topic archived. No new replies allowed.