Second while loop is not running, setting value to "nan"

Viewed 51

As shown below, I am trying to make a simple program that will find 3 averages from 3 different number groups. 1st semester, 2nd semester and the average of these two. When executed though, the program prints out the correct first-average but never goes through the second while loop ending up with "nan" as a value for the second-average.

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

using namespace std;

int main() {
    // First semester
    cout << "Enter your first semester grades (Press enter for each new grade and write \"End\" to stop): ";

    streamsize prec = cout.precision();
    double grades1;
    double sum1 = 0;
    int count1 = 0;

    while (cin >> grades1) {
        count1++;
        sum1 += grades1;
    }

    cout << "Your first semester average is: " << setprecision(3) << sum1 / count1 << setprecision(prec) << endl << endl;

    // Second semester
    cout << "Enter your second semester grades (Press enter for each new grade and write \"End\" to stop): ";

    double grades2;
    double sum2 = 0;
    int count2 = 0;

    while (cin >> grades2) {
        count2++;
        sum2 += grades2;
    }

    cout << "Your second semester average is: " << setprecision(3) << sum2 / count2 << setprecision(prec) << endl;
    cout << "Your two semester average is: " << setprecision(3) << (sum1 / count1 + sum2 / count2) / 2 << setprecision(prec) << endl;

    return 0;
}
3 Answers

I believe this is a problem with std::cin. I added a new check in your code after the first while loop:

if (cin.fail()) {
    cout << "Cin in failed state" << endl;
}

The above if condition works which means that cin is in failed state and is causing your second while loop not to start. I tried using cin.clear() but that did not work, I am not completely sure how to clear the failed bit on cin.

An alternate solution is to write a proper function that gets a double value from the user.

The first loop will only end if there's an error reading from std::cin, or if you press the end-of-file sequence. Both of these events will set a state in the stream object that makes all further reading from the stream to fail.

You need to use the clear function to clear this state.

cin.clear();
std::cin.ignore();

Along with the clear() function there has to be an ignore() to ignore the previous 'end-of-file' input.

Related