Pankaj Anand
Pankaj Anand

Reputation: 475

How to avoid infinite loop in this program

I am trying to solve a 3n+1 problem in C++. I want to take the input in pairs and calculate its maximum cycle length then output it.

I/P: 1 10
     100 200
     201 210
     900 1000
O/P: 1 10 25
     100 200 125
     201 210 89
     900 1000 174

Code:

#include<iostream>
using namespace std;

int clen(int i)
{
    int len=1;
    while(i!=1)
    {
        len++;
        if(i%2==0)
            i/=2;
        else
            i=3*i+1;
    }
    return len;
}

int maxclen(int a, int b)
{
    int i,len,maxlen=0;
    for(i=a;i<=b;i++)
    {
        len=clen(i);
        if(len>maxlen)
            maxlen=len;
    }
    return maxlen;
}

main()
{
    int b[10][2],l,i,len[10];
    for(i=0;;i++)
    {
        cin>>b[i][0];
        if(cin.fail())
        {
            cin.clear();
            goto a;
        }
        cin>>b[i][1];
        if(cin.fail())
            goto a;

    }
    a:
    l=i;
    for(i=0;i<=l;i++)
    {
        if(b[i][1]>b[i][0])
            len[i]=maxclen(b[i][0],b[i][1]);
        else
            len[i]=0;
    }
    for(i=0;i<l;i++)
        cout<<b[i][0]<<" "<<b[i][1]<<" "<<len[i]<<endl;
}

I want to stop entering the input whenever cin.fail() returns true but its working for few first execution of the program but after that it is entering in an infinite loop to enter the numbers and it just cant get out. Can anyone help me on this cin issue, How can I avoid this infinite loop?

Upvotes: 2

Views: 2907

Answers (2)

greatwolf
greatwolf

Reputation: 20838

You have an off-by-one error over here:

for(i=0;i<=l;i++)
{
  // ...
}

I modified your main like this to correct a couple of problems:

int main()
{
    const size_t length = 10;
    int b[length][2], len[length];

    size_t i = 0;
    while(i < length)
    {
        cin >> b[i][0];
        if(!cin) break;
        cin >> b[i][1];
        if(!cin) break;
        ++i;
    }

    for(int j = 0; j < i; j++)
    {
        if(b[j][1] > b[j][0])
            len[j] = maxclen(b[j][0], b[j][1]);
        else
            len[j] = 0;
    }
    for(int j = 0; j < i; j++)
        cout << b[j][0] << " " << b[j][1] << " " << len[j] << endl;
}

Upvotes: 0

matiu
matiu

Reputation: 7725

I found it died if you hit ctrl+d (eof) after only entering one number.

Maybe try adding another 'clear' the error state there:

main()
{
    int b[10][2],l,i,len[10];
    for(i=0;;i++)
    {
        cin>>b[i][0];
        if(cin.fail())
        {
            cin.clear();
            goto a;
        }
        cin>>b[i][1];
        if(cin.fail())
        {
            cin.clear(); // ADDED LINE
            goto a;
        }
    }
 ...

Though I wasn't able to reproduce the error 100% .. that seemed to help the behaviour with me.

Also your array is only 10 long .. maybe it's reading too much and going into some weird state ?

Upvotes: 1

Related Questions