Accelerated C++ Solution to Exercise 3-6

Exercise 3-6

The average-grade computation in §3.1/36 might divide by zero if the student didn’t enter any grades. Division by zero is undefined in C++, which means that the implementation is permitted to do anything it likes. What does your C++ implementation do in this case? Rewrite the program so that its behavior does not depend on how the implementation treats division by zero.

Solution

Before changing any codes, let me try running the program like this:

  • Test 1: do not supply any grades at all.
  • Test 2: supply mid-term and final-exam grades, but not supply the homework grades.

Test 1

Please enter your first name: Johnny
Hello, Johnny!
Please enter your midterm and final exam grades: ^Z
Enter all your homework grades, followed by end-of-file: Your final grade is nan

Test 2

Please enter your first name: Johnny
Hello, Johnny!
Please enter your midterm and final exam grades: 80
90
Enter all your homework grades, followed by end-of-file: ^Z
Your final grade is nan

In both tests, because of the fact that I did not specify any homework grades, when the program tries to compute the average homework grade, it bump into division by zero. In my case, I ran the test via the Code::Block IDE on a Windows Vista machine, the undefined output is nan. (i.e. Not A Number).

To avoid this add an if statement to condition-check the value of count. If count is zero, exit the code peacefully with a message saying “Cannot compute final grade due to missing grades supplied – ensure you supply all grades as required.” Something like that.

 if (count == 0)
 {
 cout << "Cannot compute final grade due to missing grades supplied - ensure you supply all grades as required." << endl;
 return 1;
 }

The full code looks like this:

#include <iomanip>
#include <ios>
#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::setprecision;
using std::string;
using std::streamsize;

int main()
{
    // ask for and read the student's name
    cout << "Please enter your first name: ";
    string name;
    cin >> name;
    cout << "Hello, " << name << "!" << endl;

    // ask for and read the midterm and final grades
    cout << "Please enter your midterm and final exam grades: ";
    double midterm, final;
    cin >> midterm >> final;

    // ask for the homework grades
    cout << "Enter all your homework grades, "
            "followed by end-of-file: ";

    // the number and sum of grades read so far
    int count = 0 ;
    double sum = 0.0;

    // a variable into which to read
    double x;

    // invariant:
    //    we have read count grades so far, and
    //    sum is the sum of the first count grades
    //    after entering the last value, hit the F6 button, then enter (to indicate end of file)
    //    or hit Ctrl+z, then enter.
    while (cin >> x)
    {
        ++count;
        sum += x;
    }

    double dummy = count; // for some reason the code fails unless I add this line.

    if (count == 0)
    {
        cout << "Cannot compute final grade due to missing grades supplied - ensure you supply all grades as required." << endl;
        return 1;
    }


    // write the result
    streamsize prec = cout.precision();

     cout << "Your final grade is " << setprecision(3)
         << 0.2 * midterm + 0.4 * final + 0.4 * sum / count
         << setprecision(prec) << endl;

    return 0;

}

 

Result

Please enter your first name: Johnny
Hello, Johnny!
Please enter your midterm and final exam grades: ^Z
Enter all your homework grades, followed by end-of-file: Cannot compute final gr
ade due to missing grades supplied - ensure you supply all grades as required.

Reference

Koenig, Andrew & Moo, Barbara E., Accelerated C++, Addison-Wesley, 2000