The while Loop in C++

A while loop executes statements repeatedly while the condition is true.

The syntax for the while loop is

while (loop-continuation-condition) {

// Loop body

Statement(s);

}

Figure 5.1a shows the while-loop flowchart. The part of the loop that contains the state- loop body ments to be repeated is called the loop body. A one-time execution of a loop body is referred to as an iteration (or repetition) of the loop. Each loop contains a loop-continuation-condition, a Boolean expression that controls the execution of the body. It is evaluated each time to deter­mine if the loop body is executed. If its evaluation is true, the loop body is executed; if its evaluation is false, the entire loop terminates and the program control turns to the statement that follows the while loop.

The loop for displaying Welcome to C++! 100 times introduced in the preceding sec­tion is an example of a while loop. Its flowchart is shown in Figure 5.1b. The loop- continuation-condition is count < 100 and the loop body contains the following two statements:

In this example, you know exactly how many times the loop body needs to be executed because the control variable count is used to count the number of executions. This type of loop is known as a counter-controlled loop.

Here is another example to help understand how a loop works:

int sum = 0, i = 1;

while (i < 10)

{

sum = sum + i;

i++;

}

cout << “sum is ” << sum; // sum is 45

If i < 10 is true, the program adds i to sum. Variable i is initially set to 1, then is incre­mented to 2, 3, and up to 10. When i is 10, i < 10 is false, so the loop exits. Therefore, the sum is 1 + 2 + 3 + … + 9 = 45.

What happens if the loop is incorrectly written as follows?

int sum = 0, i = 1;

while (i < 10)

{

sum = sum + i;

}

This loop is infinite, because i is always 1 and i < 10 will always be true.

int count = 0;

while (count <= 100)

{

cout << “Welcome to C++!\n”;

count++;

}

Recall that Listing 3.4 SubtractionQuiz.cpp gives a program that prompts the user to enter an answer for a question on subtraction. Using a loop, you can rewrite the program to let the user enter a new answer until it is correct, as shown in Listing 5.1.

Listing 5.1   RepeatSubtractionQuiz.cpp

1 #include <iostream>

2 #include <ctime> // for time function

3 #include <cstdlib> // for rand and srand functions

4 using namespace std;

5

6 int main()

7 {

8     // 1. Generate two random single-digit integers

9      srand(time(0));

10    int number1 = rand() % 10;

11    int number2 = rand() % 10;

12

13     // 2. If number1 < number2, swap number1 with number2

14     if (number1 < number2)

15     {

16           int temp = number1;

17           number1 = number2;

18           number2 = temp;

19      }

20

21        // 3. Prompt the student to answer “What is number1 – number2”

22        cout << “What is ” << number1 << ” – ” << number2 << “? “;

23        int answer;

24        cin >> answer;

25

26        // 4. Repeatedly ask the user the question until it is correct

27         while (number1 – number2 != answer)

28         {

29               cout << “Wrong answer. Try again. What is “

30               << number1 << ” – ” << number2 << “? “;

31                cin >> answer;

32           }

33

34       cout << “You got it!” << endl;

35

36        return 0;

37 }

The loop in lines 27-32 repeatedly prompts the user to enter an answer when numberl – number2 != answer is true. Once numberl – number2 != answer is false, the loop exits.

1. Case Study: Guessing Numbers

The problem is to guess what number a computer has in mind. You will write a program that randomly generates an integer between 0 and l00, inclusive. The program prompts the user to enter a number continuously until the number matches the randomly generated number. For each user input, the program tells the user whether the input is too low or too high, so the user can make the next guess intelligently. Here is a sample run:

The magic number is between 0 and 100. To minimize the number of guesses, first enter 50. If your guess is too high, the magic number is between 0 and 49. If your guess is too low, the magic number is between 51 and 100. So, you can eliminate half of the numbers from consideration after one guess.

How do you write this program? Do you immediately begin coding? No. It is important to think before coding. Think how you would solve the problem without writing a program. First you need to generate a random number between 0 and 100, inclusive, then prompt the user to enter a guess, and then compare the guess with the random number.

It is a good practice to code incrementally one step at a time. For programs involving loops, if you don’t know how to write a loop, you may first write the code for executing the loop one time, and then figure out how to execute the code repeatedly in a loop. For this program, you may create an initial draft, as shown in Listing 5.2

Listing 5.2 GuessNumberOneTime.cpp

1 #include <iostream>

2 #include <cstdlib>

3 #include <ctime> // Needed for the time function

4 using namespace std;

5

6 int main()

7 {

8     // Generate a random number to be guessed

9    srand(time(0));

10   int number = rand() % 101;

11

12    cout << “Guess a magic number between 0 and 100”;

13

14    // Prompt the user to guess the number

15    cout << “\nEnter your guess: “;

16    int guess;

17    cin >> guess;

18

19    if (guess == number)

20    cout << “Yes, the number is ” << number << endl;

21    else if (guess > number)

22    cout << “Your guess is too high” << endl;

23    else

24    cout << “Your guess is too low” << endl;

25

26    return 0;

27 }

When you run this program, it prompts the user to enter one guess. To let the user enter a guess repeatedly, you may put the code in lines 15-24 in a loop as follows:

while (true)

{

// Prompt the user to guess the number

cout << “\nEnter your guess: “;

cin >> guess;

if (guess == number)

cout << “Yes, the number is ” << number << endl;

else if (guess > number)

cout << “Your guess is too high” << endl;

else

cout << “Your guess is too low” << endl;

} // End of loop

This loop repeatedly prompts the user to enter a guess. However, this loop is incorrect, because it never terminates. When guess matches number, the loop should end. So, the loop can be revised as follows:

while (guess != number)

{

// Prompt the user to guess the number

cout << “\nEnter your guess: “;

cin >> guess;

if (guess == number)

cout << “Yes, the number is ” << number << endl;

else if (guess > number)

cout << “Your guess is too high” << endl;

else

cout << “Your guess is too low” << endl;

} // End of loop

The complete code is given in Listing 5.3.

Listing 5.3 GuessNumber.cpp

1 #include <iostream>

2 #include <cstdlib>

3 #include <ctime> // Needed for the time function

4 using namespace std;

5

6 int main()

7 {

8     // Generate a random number to be guessed

9     srand(time(0));

10    int number = rand() % 101;

11

12    cout << “Guess a magic number between 0 and 100”;

13

14    int guess = -1;

15    while (guess != number)

16    {

17        // Prompt the user to guess the number

18        cout << “\nEnter your guess: “;

19        cin >> guess;

20

21        if (guess == number)

22           cout << “Yes, the number is ” << number << endl;

23        else if (guess > number)

24           cout << “Your guess is too high” << endl;

25        else

26           cout << “Your guess is too low” << endl;

27    } // End of loop

28

29    return 0;

30 }

The program generates the magic number in line 10 and prompts the user to enter a guess repeatedly in a loop (lines 15-27). For each guess, the program checks if it is correct, too high, or too low (lines 21-26). When the guess is correct, the program exits the loop (line 15). Note that guess is initialized to -1. Initializing it to a value between 0 and 100 would be wrong, because that could be the number guessed.

2. Loop Design Strategies

Writing a correct loop is not an easy task for novice programmers. Consider three steps when writing a loop.

Step 1: Identify the statements that need to be repeated.

Step 2: Wrap these statements in a loop as follows:

while (true)

{

Statements;

}

Step 3: Code the loop-continuation-condition and add appropriate statements for controlling the loop.

while (loop-continuation-condition)

{

Statements;

Additional statements for controlling the loop;

}

3. Case Study: Multiple Subtraction Quiz

The subtraction quiz program in Listing 3.4, SubtractionQuiz.cpp, generates just one question for each run. You can use a loop to generate questions repeatedly. How do you write the code to generate five questions? Follow the loop design strategy. First, identify the statements that need to be repeated. They are the statements for obtaining two random numbers, prompting the user with a subtraction question, and grading the question. Second, wrap the statements in a loop. Third, add a loop control variable and the loop-continuation-condition to execute the loop five times.

Listing 5.4 gives a program that generates five questions and, after a student answers them, reports the number of correct answers. The program also displays the time spent taking the test, as shown in the sample run.

Listing 5.4    SubtractionQuizLoop.cpp

1 #include <iostream>

2 #include <ctime> // Needed for time function

3 #include <cstdlib> // Needed for the srand and rand functions

4 using namespace std;

5

6 int main()

7 {

8    int correctCount = 0; // Count the number of correct answers

9    int count = 0; // Count the number of questions

10   long startTime = time(0);

11   const int NUMBER_OF_QUESTIONS = 5;

12

13    srand(time(0)); // Set a random seed

14

15    while (count < NUMBER_OF_QUESTIONS)

16    {

17        // 1. Generate two random single-digit integers

18        int number1 = rand() % 10;

19        int number2 = rand() % 10;

20

21        // 2. If number1 < number2, swap number1 with number2

22        if (number1 < number2)

23        {

24            int temp = number1;

25            number1 = number2;

26            number2 = temp;

27        }

28

29     // 3. Prompt the student to answer “what is number1 – number2?”

30       cout << “What is ” << number1 << ” – ” << number2 << “? “;

31       int answer;

32       cin >> answer;

33

34      // 4. Grade the answer and display the result

35      if (number1 – number2 == answer)

36       {

37          cout << “You are correct!\n”;

38           correctCount++;

39       }

40       else

41        cout << “Your answer is wrong.\n” << number1 << ” – ” <<

42        number2 << ” should be ” << (number1 – number2) << endl;

43

44        // Increase the count

45         count++;

46     }

47

48     long endTime = time(0);

49     long testTime = endTime – startTime;

50

51      cout << “Correct count is ” << correctCount << “\nTest time is “

52     << testTime << ” seconds\n”;

53

54   return 0;

55 }

The program uses the control variable count to control the execution of the loop. count is initially 0 (line 9) and is increased by 1 in each iteration (line 45). A subtraction question is displayed and processed in each iteration. The program obtains the time before the test starts in line 10, the time after the test ends in line 48, and computes the test time in line 49.

4 . Controlling a Loop with User Confirmation

The preceding example executes the loop five times. If you want the user to decide whether to continue, you can offer a user confirmation. The template of the program can be coded as follows:

char continueLoop = ‘Y’; while (continueLoop == ‘Y’)

{

// Execute the loop body once

// Prompt the user for confirmation

cout << “Enter Y to continue and N to quit: “;

cin >> continueLoop;

}

You can rewrite Listing 5.4 with user confirmation to let the user decide whether to advance to the next question.

5. Controlling a Loop with a Sentinel Value

Another common technique for controlling a loop is to designate a special value when read­ing and processing a set of values. This special input value, known as a sentinel value, signi­fies the end of the input. A loop that uses a sentinel value to control its execution is called a sentinel-controlled loop.

Listing 5.5 gives a program that reads and calculates the sum of an unspecified number of integers. The input 0 signifies the end of the input. Do you need to declare a new variable for each input value? No. Just use a variable named data (line 8) to store the input value and use a variable named sum (line 12) to store the total. When a value is read, assign it to data (lines 9, 20) and add it to sum (line 15) if it is not zero.

Listing 5.5   SentinelValue.cpp

1 #include <iostream>

2 using namespace std;

3

4 int main()

5 {

6     cout << “Enter an integer (the input ends ” <<

7    “if it is 0): “;

8    int data;

9    cin >> data;

10

11    // Keep reading data until the input is 0

12    int sum = 0;

13    while (data != 0)

14    {

15        sum += data;

16

17        // Read the next data

18        cout << “Enter an integer (the input ends ” <<

19        “if it is 0): “;

20        cin >> data;

21     }

22

23     cout << “The sum is ” << sum << endl;

24

25     return 0;

26 }

If data is not 0, it is added to the sum (line 15) and the next items of input data are read (lines 18-20). If data is 0, the loop terminates. The input value 0 is the sentinel value for this loop. Note that if the first input read is 0, the loop body never executes, and the resulting sum is 0.

6. Input and Output Redirections

In the preceding example, if you have a lot of data to enter, it would be cumbersome to type from the keyboard. You may store the data separated by whitespaces in a text file, say input.txt, and run the program using the following command:

SentinelValue.exe < input.txt

This command is called input redirection. The program takes the input from the file input.txt rather than having the user type the data from the keyboard at runtime. Suppose the contents of the file are

2  3 4 5 6 7 8 9 12 23 32

23 45 67 89 92 12 34 35 3 1 2 4 0

The program should set sum to be 518. Note that SentinelValue.exe can be obtained using the command-line compiler command:

g++ SentinelValue.cpp -o SentinelValue.exe

Similarly, output redirection can send the output to a file rather than displaying it on the con­sole. The command for output redirection is as follows:

SentinelValue.exe > output.txt

Input and output redirection can be used in the same command. For example, the following command gets input from input.txt and sends output to output.txt:

SentinelValue.exe < input.txt > output.txt

Run the program to see what contents are in output.txt.

7. Reading All Data from a File

Listing 4.11 reads three numbers from the data file. If you have many numbers to read, you will have to write a loop to read all of them. If you don’t know how many numbers are in the file and want to read them all, how do you know the end of file? You can invoke the eof() function on the input object to detect it. Listing 5.6 revises Listing 4.10 SimpleFileInput.cpp to read all numbers from the file numbers.txt.

Listing 5.6   ReadAllData.cpp

1 #include <iostream>

2 #include <fstream>

3 using namespace std;

4

5 int main()

6 {

7     // Open a file

8    ifstream input(“score.txt”);

9

10    double sum = 0;

11    double number;

12    while (!input.eof()) // Continue if not end of file

13    {

14       input >> number; // Read data

15       cout << number << ” “; // Display data

16       sum += number;

17    }

18

19    input.close();

20

21    cout << “\nSum is ” << sum << endl;

22

23    return 0;

24 }

The program reads data in a loop (lines 12-17). Each iteration of the loop reads one number.

The loop terminates when the input reaches the end of file.

When there is nothing more to read, eof() returns true. For this program to work cor­rectly, there shouldn’t be any blank characters after the last number in the file. In Chapter 13, we will discuss how to improve the program for handling the unusual cases with blank char­acters after the last number in the file.

Source: Liang Y. Daniel (2013), Introduction to programming with C++, Pearson; 3rd edition.

Leave a Reply

Your email address will not be published. Required fields are marked *