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.

有帮助吗?

解决方案

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

其他提示

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.

You need to check the fail bit after reading the height

See - fail bit

This is set if it was unable to read an integer. You then need to eat some input and issue a message

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()

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top