John
John

Reputation: 5

How can I properly use a flag controlled loop so that a specific task is performed only once?

I am making a program that asks the user for two rational numbers and depending on whether the user chooses to add or subtract, my program will perform the task and then have to option to continue adding or subtracting or exiting.

So far I have most of my coding done, but am having a problem with writing a flag controlled loop. For my program, a show menu will appear that will ask the user whether they want to subtract, add or quit.

If the user chooses to add, the screen will clear and a title should appear at the top that says "Addition of rational numbers". This title should only appear once, and after this my program will ask the user to enter a rational number.

Since the program is supposed to add two rational numbers, after the user inputs the first rational number my program will ask the user for another rational number.

So in total, my program will ask the question two times.

Question: The problem that I am having is that once the title "Addition of rational numbers" appears and my program asks the user for the number the second time, the title will come out again. I tried using a flag controlled loop, but no matter what I tried it will either skip the title or repeat it every time the question is asked. Below is the code that I am referring to:

void GetRational(char state, int& num, int& den)
{
    char c;
    bool once;
    once = true;

    while (once)
    {
        if (state == 'A' || state == 'a')
        {
            cout << "Addition of rational numbers" << endl;
            once = false;
        }
        else if (state == 'S' || state == 's')
        {
            cout << "Subtraction of rational numbers" << endl;
            once = true;
        }
        else break;
    }

    while (1)
    {
        cout << "\nPlease enter a fraction (n/d): ";
        cin >> num >> c >> den;
        if (den == 0)
            cout << "\nDenominator must not be 0";
        else break;
    }
}

Upvotes: 0

Views: 788

Answers (3)

FutureJJ
FutureJJ

Reputation: 2678

Try moving bool once outside of the function GetRational(...), it may be the case that you are calling GetRational(...) multiple times and each time bool once might be getting reinitialized. So the snippet would look like this:

bool once = true;
void GetRational(char state, int& num, int& den)
{
    char c;

    while (once)
    {
        if (state == 'A' || state == 'a')
        {
            cout << "Addition of rational numbers" << endl;
            once = false;
        }
        else if (state == 'S' || state == 's')
        {
            cout << "Subtraction of rational numbers" << endl;
            once = true;
        }
        else break;
    }

    while (1)
    {
        cout << "\nPlease enter a fraction (n/d): ";
        cin >> num >> c >> den;
        if (den == 0)
            cout << "\nDenominator must not be 0";
        else break;
    }
}

As Davislor pointed out in the comments:

The problem with globals, especially globals that aren’t constants, is that any part of the program can mess around with them. That makes it very hard to track down which line of your program is causing a bug. It’s less of an issue if you split your program into modules and you can at least guarantee that only that one file could have mucked it up.

So, another option would be to use once as a static variable if you don't want to use a global variable.

Static variables when used inside function are initialized only once, and then they hold their value even through function calls.

With static variable, the code snippet would look like this:

void GetRational(char state, int& num, int& den)
{
    // will only be initialized one, at the first time call of function GetRational(...)
    static bool once = true; 
    char c;

    while (once)
    {
        if (state == 'A' || state == 'a')
        {
            cout << "Addition of rational numbers" << endl;
            once = false;
        }
        else if (state == 'S' || state == 's')
        {
            cout << "Subtraction of rational numbers" << endl;
            once = true;
        }
        else break;
    }

    while (1)
    {
        cout << "\nPlease enter a fraction (n/d): ";
        cin >> num >> c >> den;
        if (den == 0)
            cout << "\nDenominator must not be 0";
        else break;
    }
}

Read more about static keyword: here

Upvotes: 1

Kalpana R
Kalpana R

Reputation: 21

You can try this code. Use if loop.

bool once="true";
     void GetRational(char state, int& num, int& den)
        {
            char c;


                if(once=="true")
               { 
                if (state == 'A' || state == 'a')
                {
                    cout << "Addition of rational numbers" << endl;
                }
                else if (state == 'S' || state == 's')
                {
                    cout << "Subtraction of rational numbers" << endl;

                }
                else { }
          }

            while (1)
            {   
                once="false";
                cout << "\nPlease enter a fraction (n/d): ";
                cin >> num >> c >> den;
                if (den == 0) 
                    cout << "\nDenominator must not be 0";
                else break;
            }
        }

Upvotes: 0

Davislor
Davislor

Reputation: 15144

To make GetRational remember the value of once the next time you invoke it, declare the variable as

static bool once = true;

The static variable will only be initiailized one time, which will be before the first call to GetRational.

Then, after you check it and before you return from GetRational, set

once = false;

This will persist between calls to GetRational.

Upvotes: 1

Related Questions