简体   繁体   中英

C++ cant exit while loop

So for my program of manipulating a vector, a choice is presented at the end of each switch case: If the letter 'q' is entered, the program is supposed to exit the while loop and end the program, but when I enter the letter 'q' , the program crashes instead of exiting properly. Why is this happening? Is it an infinite loop?

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    int rnum;
    int jnum;
    int i;
    int lim = 5;
    char choice='b';
    vector<int> jersey(lim);
    vector<int> rating(lim);

    cout << "MENU" << endl;
    cout << "a - Add player" << endl;
    cout << "d - Remove player" << endl;
    cout << "u - Update player rating" << endl;
    cout << "r - Output players above a rating" << endl;
    cout << "o - Output roster" << endl;
    cout << "q - Quit" << endl;
    cout << "" << endl;
    cout << "Choose an option:" << endl;

    cin >> choice;

    while(choice != 'q') {

        switch(choice) {

        case 'a' :
            // addplayer
            for(int i = 0; i<=lim-1; i++)
            {
                cout << "Enter a new player's jersey number:" << endl;
                cin >> jersey.at(i);
                cout <<"Enter the player's rating:" << endl;
                cin >> rating.at(i);

            }

            cout << "Choose an option:" << endl;
            cin >> choice;
        break;

       case 'u' :
            // updat rating
            cout << "Enter a jersey number:" << endl;
            cin >> jnum;

            for( int i = 0; i <= lim-1; i++ )
            {
                if( jersey.at(i) == jnum )
                {
                    cout << "Enter a new rating for player:" <<endl;
                    cin >> rnum;
                    rating.at(i) = rnum;

                    break;
                }
            }

            cout << "Choose an option:" << endl;
            cin >> choice;
        break;

       case 'o':
            cout << "ROSTER" << endl;
            for(int i = 0; i<lim; i++)
            {
                cout << "Player "<<i+1 <<" -- Jersey number:" << " " <<jersey.at(i) << ", " << "Rating: " << rating.at(i) << endl;
            }

            cout << "Choose an option:" << endl;
            cin >> choice;
        break;

        case 'd':
            cout << "Enter a jersey number:" << endl;
            cin >> jnum;

            for( std::vector<int>::iterator spot = jersey.begin(); spot != jersey.end(); ++spot )
            {
                if( *spot == jnum )
                {
                    jersey.erase( spot );
                    rating.erase( spot );
                    lim = jersey.size();
                }
            }

            cout << "Choose an option:" << endl;
            cin >> choice;
        break;

        case 'r':
            cout << "Enter a rating:" << endl;
            cin >> rnum;

            for( int i = 0; i <= lim-1; i++ )
            {
                if( rating.at(i) >= rnum )
                {
                    cout << "Player "<<i+1 <<" -- Jersey number:" << " " <<jersey.at(i) << ", " << "Rating: " << rating.at(i) << endl;
                }
            }

            cout << "Choose an option:" << endl;
            cin >> choice;
        break;


        default:
            cout << "Choose an option:" << endl;
            cin >> choice;
        break;

        }
    }

   return 0;
}

Your case 'd' looks incorrect. You can't use spot to erase an element from rating since spot only iterates over jersey 's elements. To fix this, and potentially solve your crash or infinite loop issue, you can replace the following code:

if( *spot == jnum )
{
    jersey.erase( spot );
    rating.erase( spot );
    lim = jersey.size();
}

With:

if( *spot == jnum )
{
    jersey.erase( spot );
    rating.erase( rating.begin() + (spot - jersey.begin()) );
    lim = jersey.size();
}

Here, spot - jersey.begin() will give you the index of the jersey you just found, adding that to rating.begin() will therefore give you the corresponding rating and allow you to properly erase it from the rating vector.

In addition, since your code allows duplicate jersey numbers, deleting a duplicate won't always delete all instances of the number. If you want to fix this, you can add spot--; after lim = jersey.size(); to ensure you don't skip over duplicate elements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM