Reputation: 55
I am having an issue with my program. I am building a pyramid program to better understand looping structures in C++. The issue is when I build and run this and I get to:
cout << "\nPlease enter the number of lines for your pyramid: ";
cin >> height;
and I type a random character such as 'K', it starts continuously(never ending) looping:
cout << "ERROR: Please enter a value between 3 and 25!" << endl;
My questions: Why does it continuously loop? What can be implemented to fix this issue?
#include <iostream>
#include <limits>
using namespace std;
void draw(int height)
{
for(int line = 0;line<=height;line++)
{
int spaces = height - line;
for(int j=1;j<=spaces;j++)
cout<<" ";
for(int i=1;i<=line*2+1;i++)
cout<<"+";
cout<<"\n";
}
}
int main()
{
int height;
do{
cout << "\nPlease enter the number of lines for your pyramid: ";
cin >> height;
if(height>3 && height<25)draw(height);
else{
cout << "ERROR: Please enter a value between 3 and 25!" << endl;
}
}while(height<3 || height>25);
cout << "\n";
return 0;
}
I have researched and found no similar issues, most common issues seems to be people not setting their conditions.
Upvotes: 1
Views: 269
Reputation: 24249
The problem is that the streaming-input operator >>
will try to only read input valid for the type you are inputting to:
int i;
std::cin >> i;
will only read integer values. When this fails, it sets a flag that can be tested for with std::cin::fail()
int i;
std::cin >> i;
if (cin.fail())
throw std::invalid_argument("Expected an int, got some other junk");
However that leaves the input in the input stream, leaving you to use one of various mechanisms to get around it.
What might be easiest is to use std::getline
to read the input line-at-a-time.
#include <string>
#include <iostream>
#include <cctype>
#include <cstdlib>
int main() {
std::string input;
int i = 0;
while (std::cin.good()) {
std::cout << "Enter a number between 3 and 25: ";
std::getline(std::cin, input);
if (input.empty()) // blank lines
continue;
if (isdigit(input[0])) {
i = atoi(input.c_str());
if (i < 3 || i > 25) {
std::cout << "Invalid number, " << input << '\n';
continue;
}
// valid input, stop the loop
break;
}
std::cout << "Unrecognized/non-numeric input: \"" << input << "\"\n";
}
if (i == 0) // we left the loop because cin.good() was false
return 0;
std::cout << "You entered " << i << '\n';
}
Live demo: http://ideone.com/KRHM3V
Upvotes: 2
Reputation: 5359
This is because you have declared height
as int
and whenever cin
sees a char
being entered skips without taking the input. So the input stays in the input buffer and height
retains its older value. In this case its the garbage value and its accidentally not between 3 and 25. Hence the infinte loop.
Use cin.fail()
if you want to break if a non-integer is entered:
int Item;
cin >> Item;
while (! cin.fail())
{
Process(Item);
cin >> Item;
}
Edit: Adding answer based on your comment, input as a string. Check every position for non-digits. And if it is a valid integer, use atoi() to convert it to an integer.
Upvotes: 2
Reputation: 4738
You will have validate if input is valid. Check with code below..
if(!(cin >> height))
{
//print invalid input
break;
}
Also you can check cin.fail()
Upvotes: 0