bluebyte
bluebyte

Reputation: 560

How to get 2 ints from cin in C++?

I'am trying to get three pairs of int from user. But if i enter letters my code ran into infinitive cycle. What am I doing wrong?

struct Point
{
    int x;
    int y;
};

istream& operator>> (istream& is, Point& pt)
{
    int x, y;
    is >> x >> y;
    if (!is) 
        return is;
    pt.x = x;
    pt.y = y;
    return is;
}

int main()
{
    vector<Point> points;
    Point pt;
    while (true)
    {
        if (cin >> pt)
        {
            points.push_back(pt);
            if (points.size() == 3)
                break;
            continue;
        }
        cout << " error, try again" << endl; 
        cin.clear();
    }

    for (int i = 0; i < 3; i++)
        cout << "(" << points[i].x << ", " << points[i].y << ")" << endl;
}

Upvotes: 0

Views: 257

Answers (2)

Marcelo Cantos
Marcelo Cantos

Reputation: 185842

The while (true) ... loop never stops. The break never executes because cin >> pt keeps failing. You can't fix this with simple istream operations, since cin >> pt will never succeed once you've supplied bad input. Either expect correct input, and fail outright if it isn't:

while (points.size() < 3 && (cin >> pt))
{
    points.push_back(pt);
}
if (points.size() < 3) throw "up";

or read the input as a string and parse it as a separate operation.

While we're at it, simplify your extractor:

istream& operator>>(istream& is, Point& pt)
{
    Point p;
    if (is >> p.x >> p.y) pt = p;
    return is;
}

Upvotes: 2

Mike Seymour
Mike Seymour

Reputation: 254431

When cin >> pt fails, it leaves the end-of-line character in the stream. This causes the next extraction to fail immediately, creating the infinite loop.

Add cin.ignore() to the end of the loop to remove the end of the failed line; then the next extraction will wait for more input.

Upvotes: 1

Related Questions