#include <vector>
#include <string>
#include <ostream>
#include <sstream>
#include <iomanip>
#include <iostream>
#include <numeric>
#include <new>
struct stream_error { };
struct logic_error { };
typedef double score_type;
typedef double average_type;
// Returns a score entered by the user.
score_type getscore (const std::string & prompt)
{
score_type result;
std::string temp;
std::cout << prompt;
while (std::getline (std::cin, temp))
{
std::istringstream sstream (temp);
if (sstream >> result)
{
if (sstream >> temp && ! temp.empty ())
{
std::cout << "Please just enter one score per line.\n";
continue;
}
return result;
}
std::cout << "That's not a valid score. Try again.\n";
}
// Program flow will never reach this point.
throw logic_error ();
}
// Returns an iterator to a minimal element of a sequence.
template <typename iterator>
iterator find_lowest (iterator iter, iterator end)
{
if (iter == end) throw logic_error ();
iterator result (iter);
for (++ iter; iter != end; ++ iter)
if (* iter < * result)
result = iter;
return result;
}
// Returns the mean of all the elements of the score vector.
average_type average (std::vector <score_type> & v)
{
if (v.empty ()) throw logic_error ();
return
static_cast <average_type>
(std::accumulate (v.begin (), v.end (),
static_cast <score_type> (0)))
/ v.size ();
}
int main ()
{
try
{
{
using std::ios_base;
ios_base::iostate exceptions =
ios_base::failbit | ios_base::badbit;
std::cout.exceptions (exceptions); // often a good idea
std::cin.exceptions (exceptions); // often a bad idea
}
std::vector <score_type> scores;
// Ask the user for 5 score_type objects.
for (int i = 0; i != 5; ++ i)
{
std:
stringstream sstream;
sstream << "Enter the score for game " << i + 1 << ".\n";
scores.push_back (getscore (sstream.str ()));
}
// Find and erase a minimal score.
scores.erase (find_lowest (scores.begin (), scores.end ()));
// Compute and display the average of the remaining scores.
std::cout << "The average score was "
<< std::fixed << std::setprecision (4)
<< average (scores) << ".\n";
return 0;
}
catch (logic_error &)
{
std::cerr << "This should never happen.\n";
return 1;
}
catch (std::bad_alloc & e)
{
std::cerr << "There was a fatal memory allocation error.\n";
return 1;
}
catch (std::ios_base::failure & e)
{
std::cerr << "There was a fatal input or output error.\n";
return 1;
}
catch (...)
{
std::cerr << "There was a fatal error.\n";
return 1;
}
}