0

I keep getting stuck in an infinite loop with the code. I have to make it so you can exit using the sentinel 'q' but not iterate more than 20 times. Any help will be appreciated as I'm only new to programming.

#include <iostream>

using namespace std;

int main()
{
    int option; // If new member or existing member or exit
    char SENTINEL = 'q';
while(option != SENTINEL)
{
    for(int count = 0; count <= 20; count++)
    {   
        // Display menu
        cout << "Welcome to the forum.\n";
        cout << "Are you:\n";
        cout << "1. A new member\n";
        cout << "2. An existing member" << endl;
        cout << "To exit press 'q'\n";
        cin >> option;

        if (option == 1)
        {
            char new_name[20]; // Array to hold new member 

            cout << "You're a new member.\n"; 
            cout << "Please enter your first name followed ";
            cout << "by your last name.\n";
            cout << "Then press return.\n";

            cin >> new_name; // User enter their name
        }
        else if (option == 2)
        {
            cout << "You're an existing member." << endl;
        }
    } 
}
}
DEdwards
  • 11
  • 3

7 Answers7

1

You need to do the following:

  1. Get rid of the while loop. You need to use one loop that has multiple conditions or break from it within the loop.
  2. Make option a char instead of an int. It doesn't make sense to compare option against SENTINEL because they are different types. Making option a char will fix this problem.
  3. Use the string class instead of char array with 20 elements. Anyone whose first and last names are longer than 20 characters will cause a buffer overrun. string safer and will automatically expand if needed.

#include <iostream>
#include <string>

using namespace std;

int main()
{
    char option; // If new member or existing member or exit
    char SENTINEL = 'q';

    for(int count = 0; count <= 20; count++)
    {   
        // Display menu
        cout << "Welcome to the forum.\n";
        cout << "Are you:\n";
        cout << "1. A new member\n";
        cout << "2. An existing member" << endl;
        cout << "To exit press 'q'\n";
        cin >> option;
        cin.get(); // discard newline char

        if (option == '1')
        {
            string new_name; // string to hold new member 

            cout << "You're a new member.\n"; 
            cout << "Please enter your first name followed ";
            cout << "by your last name.\n";
            cout << "Then press return.\n";

            getline(cin, new_name); // User enter their name
        }
        else if (option == '2')
        {
            cout << "You're an existing member." << endl;
        }
        else if (option == SENTINEL) {
            break; // break from the loop
        }
    } 
}
PC Luddite
  • 5,883
  • 6
  • 23
  • 39
1

Check this: Need to take newline character using getchar()

#include <iostream>

using namespace std;

int main()
{
    int option; // If new member or existing member or exit
    char SENTINEL = 'q';
while(option != SENTINEL)
{
    for(int count = 0; count <= 20; count++)
    {
        // Display menu
        cout << "Welcome to the forum.\n";
        cout << "Are you:\n";
        cout << "1. A new member\n";
        cout << "2. An existing member" << endl;
        cout << "3. To exit press '3'\n";
        cin >> option;
        getchar();
        if (option == 1)
        {
            char new_name[20]; // Array to hold new member

            cout << "You're a new member.\n";
            cout << "Please enter your first name followed ";
            cout << "by your last name.\n";
            cout << "Then press return.\n";

            cin >> new_name; // User enter their name
        }
        else if (option == 2)
        {
            cout << "You're an existing member." << endl;
        }else if(option == 3)
        {
            exit(0);
        }
    }
}
}
Animesh Kumar Paul
  • 2,241
  • 4
  • 26
  • 37
0

You can have multiple conditions on your for loop so that it exits when count exceeds 20 or option equals 'q'. It'll look something like this:

int main()
{
    int option; // If new member or existing member or exit
    char SENTINEL = 'q';

    for(int count = 0; ((count <= 20)&&(option != SENTINEL)); count++)
   {   
       // Display menu
       cout << "Welcome to the forum.\n";
       cout << "Are you:\n";
       cout << "1. A new member\n";
       cout << "2. An existing member" << endl;
       cout << "To exit press 'q'\n";
       cin >> option;

       if (option == '1')
       {
           char new_name[20]; // Array to hold new member 

           cout << "You're a new member.\n"; 
           cout << "Please enter your first name followed ";
           cout << "by your last name.\n";
           cout << "Then press return.\n";

           cin >> new_name; // User enter their name
       }
       else if (option == '2')
       {
           cout << "You're an existing member." << endl;
       }
   } 

}

Olan
  • 62
  • 7
0

Test the sentinel condition in the for loop as well?

for(int count = 0; count <= 20 && option != SENTINEL; count++)

Note that to avoid undefined behavior, you should initialize option to some value (other than SENTINEL) or you're working with whatever garbage was left on the stack.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
0

First of all :

option != SENTINEL this line does not make sense you cannot compare an integer to a character, either you make both variables int or char data types

Change char new_name[20]; to an string array to save from a lot of trouble.

In addition when the user inputs q you should exit from the loop or the program so why not use the exit(1) method.

  char option ;
char SENTINEL = 'q';
while(option != SENTINEL)
{
    // Display menu
    cout << "Welcome to the forum.\n";
    cout << "Are you:\n";
    cout << "1. A new member\n";
    cout << "2. An existing member" << endl;
    cout << "To exit press 'q'\n";
    cin >> option; //<-- 1 and 2 will be char variable 

    if (option == '1')  
    {
        string new_name[20]; 

       for(int count = 0; count < 20; count++)
       {
        cout << "You're a new member.\n"; 
        cout << "Please enter your first name followed ";
        cout << "by your last name.\n";
        cout << "Then press return.\n";

        cin >> new_name[count]; 
      }
    }
    else if (option == '2')
    {
        cout << "You're an existing member." << endl;
    }
    else if (option == 'q')
    {
       exit(1);   // to exit from the loop  
    }
} 
Lamour
  • 3,002
  • 2
  • 16
  • 28
0

May you just...

#include <iostream>
#include <string>
#include <limits>

int main() {
    char option;
    const char sentinel = 'q';

    bool quit = false;
    for(int count = 0; count <= 20 && !quit; count++) {   
        std::string name;

        bool invalid;
        do {
            invalid = false;

            // Display menu
            std::cout << "Welcome to the forum.\n";
            std::cout << "Are you:\n";
            std::cout << "1. A new member\n";
            std::cout << "2. An existing member\n";
            std::cout << "To exit press '" << sentinel << "'\n";

            std::cin >> option;
            switch(option) {
                case '1':
                    std::cout << "You're a new member.\n"; 
                    std::cout << "Please enter your first name followed ";
                    std::cout << "by your last name.\n";
                    std::cout << "Then press return.\n";

                    std::cin >> name;
                    break;

                case '2':
                    std::cout << "You're an existing member.\n";
                    break;

                case sentinel:
                    quit = true;
                    break;

                default:
                    std::cout << "You entered invalid input!\n\n";
                    std::cin.clear();
                    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

                    invalid = true;
                    continue;
            }
        } while(invalid);
    }

    std::cout << "Exiting...\n";
    return 0;
}

Pitfalls

You had several issues... including:

  • using namespace std;: Not a good idea any day of the week.
  • Your while() loop didn't made any sense. It simply wouldn't "override" or otherwise take control over the for loop.
  • If option is of type int, there's no way for it to notice the sentinel input. std::cin would simply set the fail bit and you would not notice it.
  • You had a char[20] somewhere. That's sugar for stack overflows/buffer overruns and other subtle bugs, not to even mention security issues... std::string fixes that.
  • Boolean flags (such as invalid and quit) are useful to get out of long-nested loops.
  • std::cin.clear() cleans up any errors. Meanwhile, std::cin.ignore() allows you to ignore all the contents of a previous garbage input line.
  • "Minor" design issues all over the place.
3442
  • 8,248
  • 2
  • 19
  • 41
  • I don't think `using namespace std;` is bad for simple programs like this, and your program doesn't achieve what the OP wants. I agree with your points otherwise. – PC Luddite Sep 26 '15 at 05:11
  • @PCLuddite: [Why is "using namespace std"; considered bad practice?](http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice). Well, let's not start a discusion for this. I just don't agree with using it anywhere. With respect to "your program doesn't achieve what the OP wants", what do you mean by that? It does what the OP is asking for... – 3442 Sep 26 '15 at 05:16
0

I want to complement the other answers because

  1. they do not explain why you entered an infinite loop when you made "option" and integer instead of a char.
  2. there is still a possibly undesirable behaviour.

1-) Try this snippet:

    int option=-1;
    cout<<"The initial value of option is: "<<option<<endl;
    cout<<"Input a new value, please: "<<endl;
    cin >> option;
    cout<<"After your input, it is: "<<option<<endl;

If you input a number (like 123), it will receive it's value correctly. If you type a letter (like q), it will become 0. If you type a mix of numbers and letters, it will try to extract a number from it until you reach a letter ( say, if you type 12q34, option will become 12 and "q34" will remain in cin's buffer)

In your code, whenever you type 'q', cin will make option go to 0, but won't forget its value. So after an iteration, it won't take any input from you anymore because it still has the previous value in its memory and won't get rid of it.


2-) So should you make option a char? Yes and no. If you do, typing something like "123" will create a new member with the name "23", because your program would take the '1' from "123", enter the conditional for a new member, automatically dump "23" to name and immediately go back to your first prompt. If that's acceptable( if you trust your user that much), go ahead. Otherwise, use something like std::string and it's compare method.

guivenca
  • 159
  • 1
  • 11