// // like ave.cpp, but redesigned to allow alternative streams // #include #include #include #include // for fabs #include // for setprecision using namespace std; const double EPSILON = 1e-6; // return average of double inputs as a double or 0.0 if there are no inputs // // note the istream is passed by reference // double average(istream& input) { double sum = 0.0; double number; int count = 0; input >> number; while ( input ) { sum += number; ++count; input >> number; } return count == 0 ? 0.0 : sum / count; } // report average to three significant places // (written as a separate function to illustrate output streams) // // again, note the ostream is passed by reference // void report_average(ostream& output, double value) { output << "Average: " << setprecision(3) << std::fixed << value; } int main() { { // test the average function istringstream nums("5.5 7.0 10.0"); double a = average(nums); assert(fabs(a - 7.5) < EPSILON); istringstream empty(" "); a = average(empty); assert(a == 0.0); // comparing to 0 IS safe // test the full input/output; reusing nums just to illustrate // how to update a string stream to a new value nums.clear(); nums.str("101 81 93 453 18 515"); ostringstream test_output; report_average(test_output, average(nums)); assert(test_output.str() == "Average: 210.167"); } cout << "Enter numbers (using end-of-file at end): "; double ave = average(cin); report_average(cout, ave); cout << endl; return 0; }