Thread: Program gets stuck in infinite loop

  1. #1
    Registered User
    Join Date
    Dec 2004
    Posts
    20

    Program gets stuck in infinite loop

    Can anyone figure out why this program gets stuck in certain instances? ...Whenever you enter a destination with more than one word for the city name (eg "San Antonio") it goes into an infinite loop of the menu function... I've been wracking my brain, but I can't figure it out!

    Thanks,

    -Sean

    Code:
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    void initalize(string passengers[][6][4]);
    void menu(string passengers[][6][4]);
    void enterpass(string passengers[][6][4]);
    void dispsingle(string passengers[][6][4]);
    void dispall(string passengers[][6][4]);
    
    void initalize(string passengers[][6][4])
    {
        int a,b;
        for(a=0;a<10;a++)
        {
            for(b=0;b<6;b++)
            {
                passengers[a][b][0] = "\0";
            }
        }
    }
    
    void menu(string passengers[][6][4])
    {
        int choice=0;
        while (choice == 0)
        {
            cout << "Menu" << endl << "1) Enter passenger" << endl << "2) Display single passenger info" << endl << "3) Display all passengers" << endl << "4) Exit program" << endl;
            cout << "Selection: ";
            cin >> choice;
            switch (choice)
            {
            case 1:
                {
                    enterpass(passengers);
                    choice = 0;
                    break;
                }
            case 2:
                {
                    dispsingle(passengers);
                    choice = 0;
                    break;
                }
            case 3:
                {
                    dispall(passengers);
                    choice = 0;
                    break;
                }
            case 4:
                {
                    cout << "Thank you for using Lab 5!" << endl;
                    break;
                }
            }
        }
    }
    
    void enterpass(string passengers[][6][4])
    {
        int row=0, column=0;
        while (row != -1 && column != -1)
        {
            cout << endl << "Which passenger? (Format: row column) Use 0 0 to stop ";
            cin >> row >> column;
            row -= 1;
            column -=1;
            if (row > 9 || row < -1)
            {
                cout << "Invalid row" << endl;
            }
            else if (column > 5 || column < -1)
            {
                cout << "Invalid column" << endl;
            }
            else if (row > -1)
            {    
                cout << endl << "First name: ";
                cin >> passengers[row][column][0];
                cout << "Last name: ";
                cin >> passengers[row][column][1];
                cout << "Social Security Number: ";
                cin >> passengers[row][column][2];
                cout << "Destination city: ";
                getline(cin, passengers[row][column][3], '\n');
            }
        }
    }
    
    void dispsingle(string passengers[][6][4])
    {
        int row=-1, column=-1;
        cout << endl << "Enter row and column: ";
        cin >> row >> column;
        row -=1;
        column -= 1;
        if (row < 0 || column < 0 || row > 9 || column > 5)
        {
            cout << "Invalid Passenger!";
            return;
        }
        else 
        {
            cout << endl << "Displaying information for row " << row+1 << ", column " << column+1 << ":" << endl;
            cout << "First name:\t\t\t" << passengers[row][column][0] << endl;
            cout << "Last name:\t\t\t" << passengers[row][column][1] << endl;
            cout << "Social Security Number:\t\t" << passengers[row][column][2] << endl;
            cout << "Destination:\t\t\t" << passengers[row][column][3] << "\n\n";
        }
    }
    
    void dispall(string passengers[][6][4])
    {
        int a, b;
        for (a=0;a<10;a++)
        {
            if (passengers[a][0][0] != "\0" || passengers[a][1][0] != "\0" || passengers[a][2][0] != "\0" || passengers[a][3][0] != "\0" || passengers[a][4][0] != "\0" || passengers[a][5][0] != "\0")
            {
                cout << "Row " << a+1 << ":\t";
            }
            for (b=0;b<6;b++)
            {
                if (passengers[a][b][0] != "\0")
                {
                    cout << passengers[a][b][0] << " " << passengers[a][b][1] << "  ";
                }
                if (b == 5)
                {
                    cout << endl;
                }
            }
        }
    }
    
    int main()
    {
        string passengers[10][6][4]; 
        initalize(passengers);
        menu(passengers);
    return 0;
    }

  2. #2
    C/C++ homeyg's Avatar
    Join Date
    Nov 2004
    Location
    Louisiana, USA
    Posts
    209
    It might be easier to use char arrays with this (that would require alot of adjustments). As for the problem, I don't know.

  3. #3
    C/C++ homeyg's Avatar
    Join Date
    Nov 2004
    Location
    Louisiana, USA
    Posts
    209
    Code:
      #include <iostream>
    
    
    using namespace std;
    
    void initalize(char passengers[][6][4][40]);
    void menu(char passengers[][6][4][40]);
    void enterpass(char passengers[][6][4][40]);
    void dispsingle(char passengers[][6][4][40]);
    void dispall(char passengers[][6][4][40]);
    
    void initalize(char passengers[][6][4][40])
    {
        int a,R;
        for(a=0;a<10;a++)
        {
            for(R=0;R<6;R++)
            {
                passengers[a][R][0][0] = '\0';
            }
        }
    }
    
    void menu(char passengers[][6][4][40])
    {
        int choice=0;
        while (choice == 0)
        {
            cout << "Menu" << endl << "1) Enter passenger" << endl << "2) Display single passenger info" << endl << "3) Display all passengers" << endl << "4) Exit program" << endl;
            cout << "Selection: ";
            cin >> choice;
            switch (choice)
            {
            case 1:
                {
                    enterpass(passengers);
                    choice = 0;
                    break;
                }
            case 2:
                {
                    dispsingle(passengers);
                    choice = 0;
                    break;
                }
            case 3:
                {
                    dispall(passengers);
                    choice = 0;
                    break;
                }
            case 4:
                {
                    cout << "Thank you for using LaR 5!" << endl;
                    break;
                }
            }
        }
    }
    
    void enterpass(char passengers[][6][4][40])
    {
        int row=0, column=0;
        while (row != -1 && column != -1)
        {
            cout << endl << "Which passenger? (Format: row column) Use 0 0 to stop ";
            cin >> row;
            cin >> column;
            cin.get();
            row -= 1;
            column -=1;
            if (row > 9 || row < -1)
            {
                cout << "Invalid row" << endl;
            }
            else if (column > 5 || column < -1)
            {
                cout << "Invalid column" << endl;
            }
            else if (row > -1)
            {    
                cout << endl << "First name: ";
                cin.getline(passengers[row][column][0], 40);
                cout << "Last name: ";
                cin.getline(passengers[row][column][1], 40);
                cout << "Social Security NumRer: ";
                cin.getline(passengers[row][column][2], 40);
                cout << "Destination city: ";
                cin.getline(passengers[row][column][3], 40);
            }
        }
    }
    
    void dispsingle(char passengers[][6][4][40])
    {
        int row=-1, column=-1;
        cout << endl << "Enter row and column: ";
        cin >> row >> column;
        row -=1;
        column -= 1;
        if (row < 0 || column < 0 || row > 9 || column > 5)
        {
            cout << "Invalid Passenger!";
            return;
        }
        else 
        {
            cout << endl << "Displaying information for row " << row+1 << ", column " << column+1 << ":" << endl;
            cout << "First name:\t\t\t" << passengers[row][column][0] << endl;
            cout << "Last name:\t\t\t" << passengers[row][column][1] << endl;
            cout << "Social Security NumRer:\t\t" << passengers[row][column][2] << endl;
            cout << "Destination:\t\t\t" << passengers[row][column][3] << "\n\n";
        }
    }
    
    void dispall(char passengers[][6][4][40])
    {
        int a, R;
        for (a=0;a<10;a++)
        {
            if (passengers[a][0][0] != '\0' || passengers[a][1][0] != '\0' || passengers[a][2][0] != '\0' || passengers[a][3][0] != '\0' || passengers[a][4][0] != '\0' || passengers[a][5][0] != '\0')
            {
                cout << "Row " << a+1 << ":\t";
            }
            for (R=0;R<6;R++)
            {
                if (passengers[a][R][0] != '\0')
                {
                    cout << passengers[a][R][0] << " " << passengers[a][R][1] << "  ";
                }
                if (R == 5)
                {
                    cout << endl;
                }
            }
        }
    }
    
    int main()
    {
        char passengers[10][6][4][40]; 
        initalize(passengers);
        menu(passengers);
    return 0;
    }
    Everything works and is char oriented now. The 'b' variables in the code are causing the bold problem, lol, changed all b's to R's. You should worship char arrays. They are the best thing in the language.
    Last edited by homeyg; 02-07-2005 at 11:06 PM.

  4. #4
    Registered User
    Join Date
    Dec 2004
    Posts
    20
    As someone who used to program exclusively in C, I know char arrays but I wanted to try a C++/STL approach-- besides, when you can append, modify, and basically do whatever you want with strings without worrying about length--- w00t!! I hate having to write bounds checking, dynamic memory allocation, etc, all the time just to do simple things.

    Thanks for the code-- I appreciate ya taking a look at it!

    Still, does anyone know why the original code caused a problem? (Really, I'm just curious now, and I can't seem to find rhyme or reason for it)

    -Sean

  5. #5
    C/C++ homeyg's Avatar
    Join Date
    Nov 2004
    Location
    Louisiana, USA
    Posts
    209
    I had no clue what was causing the problem, but I seriously can solve any problem with char arrays (sounds pretty crazy, huh?). I only use the string class if it is a must (if I don't want to waste memory).

  6. #6
    Registered User
    Join Date
    Dec 2004
    Posts
    32
    Quote Originally Posted by Xanth
    Still, does anyone know why the original code caused a problem? (Really, I'm just curious now, and I can't seem to find rhyme or reason for it)

    -Sean
    Yes the problem is mixing cin and getline. cin leaves a new line in the stream and since this is a delimiter for getline you can see the results. google for "mixing cin and getline" or something similar can explain more. You just need to add cin.ignore(); this will ignore one character from the stream.
    Code:
               cout << "Social Security Number: ";
                cin >> passengers[row][column][2];
                cout << "Destination city: ";
                cin.ignore();
                getline(cin, passengers[row][column][3], '\n');
            }

  7. #7
    Registered User
    Join Date
    Dec 2004
    Posts
    20
    Wait, do you mean to say that cin is leaving a newline in the space? (eg "Bob Bobo" would be "Bob'\n'Bobo" instead of "Bob'\0'Bobo")

    As I understand the getline function, with three parameters it should only input data until the third parameter (the newline character in this case) occurs. Is something wrong there?

  8. #8
    Registered User
    Join Date
    Dec 2004
    Posts
    32
    Quote Originally Posted by Xanth
    Wait, do you mean to say that cin is leaving a newline in the space? (eg "Bob Bobo" would be "Bob'\n'Bobo" instead of "Bob'\0'Bobo")
    No, in the input stream, cin reads up to the '\n' and leaves that in the stream. So now what is in the input stream for getline to find is the '\n'.

    Quote Originally Posted by Xanth
    As I understand the getline function, with three parameters it should only input data until the third parameter (the new line character in this case) occurs.
    Yes this is correct. Also the '\n' is the default if none is specified.
    If you wanted to you could change the delimiter to something else that would work to.
    Code:
    getline(cin, passengers[row][column][3], '#');
    Quote Originally Posted by Xanth
    Is something wrong there?
    No

    Also a search of the board might explain more as this a common question.

  9. #9
    Registered User
    Join Date
    Dec 2004
    Posts
    20
    Ah, I see the light and once again am humbled (read: feel like an idiot!) One last question, since I can't seem to find the answer to it anywhere: is there anyway to prevent the need to hit return twice (once after entering the data, and then once more)?

    I changed the line cin.getline(passengers[row][column][3], 40) to just getline(cin, passengers[row][column[3])... I figured using cin.putback('\n') would eliminate the need for hitting enter twice, but this just threw the program into the infinite loop again.

  10. #10
    Registered User major_small's Avatar
    Join Date
    May 2003
    Posts
    2,787
    Quote Originally Posted by Xanth
    As I understand the getline function, with three parameters it should only input data until the third parameter (the newline character in this case) occurs. Is something wrong there?
    yes and no. don't forget the getline function was overloaded by the string class. getline function from cin looks like this:
    Code:
    cin.getline(destination,length,delim)
    where it will stop reading after it reads length-1 bytes or reaches the deliminating character, whichever comes first.

    the getline function from the string class, however, looks like this:
    Code:
    getline(cin,string,delim)
    as far as I know, this stops only on the delimiter or if the istream (in this case cin) throws a flag...
    Join is in our Unofficial Cprog IRC channel
    Server: irc.phoenixradio.org
    Channel: #Tech


    Team Cprog Folding@Home: Team #43476
    Download it Here
    Detailed Stats Here
    More Detailed Stats
    52 Members so far, are YOU a member?
    Current team score: 1223226 (ranked 374 of 45152)

    The CBoard team is doing better than 99.16% of the other teams
    Top 5 Members: Xterria(518175), pianorain(118517), Bennet(64957), JaWiB(55610), alphaoide(44374)

    Last Updated on: Wed, 30 Aug, 2006 @ 2:30 PM EDT

  11. #11
    Registered User
    Join Date
    Dec 2004
    Posts
    20
    Aha! Found the getline issue! Darn MS VS 6.0 and it's bug! :P

    Thanks for the help/clarification, guys. You rule!

    -Sean

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 18
    Last Post: 07-06-2009, 07:12 AM
  2. Infinite loop!!!
    By Bizmark in forum C Programming
    Replies: 3
    Last Post: 02-21-2009, 12:09 PM
  3. Using variables in system()
    By Afro in forum C Programming
    Replies: 8
    Last Post: 07-03-2007, 12:27 PM
  4. infinite loop
    By scudshouse in forum C Programming
    Replies: 3
    Last Post: 09-12-2005, 07:30 AM
  5. Program stuck in infinite loop-->PLEASE HELP
    By Jedijacob in forum C Programming
    Replies: 5
    Last Post: 03-26-2005, 12:40 PM