- Main Page
- Files

# bmi.cpp

Go to the documentation of this file.

    00001
    00039 #include <algorithm>
    00040 #include <cstdlib>
    00041 #include <iomanip>
    00042 #include <iostream>
    00043 #include <istream>
    00044 #include <limits>
    00045 #include <locale>
    00046 #include <ostream>
    00047 #include <string>
    00048 #include <vector>
    00049
    00060 int compute_bmi(int height, int weight)
    00061 {
    00062    return static_cast<int>(weight * 10000 / (height * height) + 0.5);
    00063 }
    00064
    00066 void skip_line()
    00067 {
    00068   std::cin.ignore(std::numeric_limits<int>::max(), '\n');
    00069 }
    00070
    00079 bool get_record(std::vector<std::string>& names,
    00080                 std::vector<int>& heights,
    00081                 std::vector<int>& weights,
    00082                 std::vector<char>& sexes)
    00083 {
    00084    std::string name;
    00085    int height(0);
    00086    int weight(0);
    00087    char sex('?');
    00088
    00089   std::cout << "Name " << names.size()+1 << ": ";
    00090   if (not std::getline(std::cin, name))
    00091     return false;
    00092
    00093   // Enforce minimal sanity check on the height, which must be
    00094   // between 10 and 300 cm, or baby- to giant-size.
    00095   int const min_height(10);
    00096   int const max_height(300);
    00097   std::cout << "Height (cm): ";
    00098   if (not (std::cin >> height))
    00099     return false;
    00100   skip_line();
    00101   if (height < min_height or height > max_height)
    00102   {
    00103     std::cout << "Invalid height. Aborting.\n";
    00104     return false;
    00105   }
    00106
    00107   // Enforce minimal sanity check on the weight, which must
    00108   // be between premature-baby and giant size.
    00109   const int min_weight(1);
    00110   const int max_weight(500);
    00111   std::cout << "Weight (kg): ";
    00112   if (not (std::cin >> weight))
    00113     return false;
    00114   skip_line();
    00115   if (weight < min_weight or weight > max_weight)
    00116   {
    00117     std::cout << "Invalid weight. Aborting.\n";
    00118     return false;
    00119   }
    00120
    00121   std::cout << "Sex (M or F): ";
    00122   if (not (std::cin >> sex))
    00123     return false;
    00124   skip_line();
    00125   sex = std::toupper(sex, std::locale());
    00126   if (sex != 'M' and sex != 'F')
    00127   {
    00128     std::cout << "Invalid sex. Aborting.\n";
    00129     return false;
    00130   }
    00131
    00132   // All information has now been collected, so
    00133   // append it all to the respective vectors.
    00134   names.push_back(name);
    00135   heights.push_back(height);
    00136   weights.push_back(weight);
    00137   sexes.push_back(sex);
    00138
    00139   return true;
    00140 }
    00141
    00155 void print_table(char sex,
    00156                  std::vector<int>         const& heights,
    00157                  std::vector<int>         const& weights,
    00158                  std::vector<int>         const& bmis,
    00159                  std::vector<char>        const& sexes,
    00160                  std::vector<std::string> const& names,
    00161                  int                      threshold)
    00162 {
    00163   std::cout << "Ht(cm) Wt(kg) Sex  BMI  Name\n";
    00164
    00165   float bmi_sum(0);
    00166   long int bmi_count(0);
    00167   std::vector<int> tmpbmis; // store only the BMIs that are printed
    00168                             // to compute the median
    00169   for (std::vector<int>::size_type i(0); i != heights.size(); ++i)
    00170     if (sexes.at(i) == sex)
    00171     {
    00172       bmi_sum = bmi_sum + bmis.at(i);
    00173       ++bmi_count;
    00174       tmpbmis.push_back(bmis.at(i));
    00175       std::cout << std::setw(6) << heights.at(i)
    00176                 << std::setw(7) << weights.at(i)
    00177                 << std::setw(3) << sexes.at(i)
    00178                 << std::setw(6) << bmis.at(i);
    00179       if (bmis.at(i) >= threshold)
    00180         std::cout << '*';
    00181       else
    00182         std::cout << ' ';
    00183       std::cout << ' ' << names.at(i) << '\n';
    00184     }
    00185
    00186   // If the vectors are not empty, print basic statistics.
    00187   if (bmi_count != 0)
    00188   {
    00189     std::cout << "Mean BMI = "
    00190               << std::setprecision(1) << std::fixed << bmi_sum / bmi_count
    00191               << '\n';
    00192
    00193     // Median BMI is trickier. The easy way is to sort the
    00194     // array and pick out the middle item or items.
    00195     std::sort(tmpbmis.begin(), tmpbmis.end());
    00196     std::cout << "Median BMI = ";
    00197     // Index of median item.
    00198     int i(tmpbmis.size() / 2);
    00199     if (tmpbmis.size() % 2 == 0)
    00200       std::cout << (tmpbmis.at(i) + tmpbmis.at(i-1)) / 2.0 << '\n';
    00201     else
    00202       std::cout << tmpbmis.at(i) << '\n';
    00203   }
    00204 }
    00205
    00207 int main()
    00208 {
    00209   std::locale::global(std::locale(""));
    00210   std::cout.imbue(std::locale());
    00211   std::cin.imbue(std::locale());
    00212
    00213   std::vector<std::string> names;
    00214   std::vector<int>         heights;
    00215   std::vector<int>         weights;
    00216   std::vector<char>        sexes;
    00217   std::vector<int>         bmis;
    00218   int threshold;
    00219
    00220   std::cout << "Enter threshold BMI: ";
    00221   if (not (std::cin >> threshold))
    00222     return EXIT_FAILURE;
    00223   skip_line();
    00224
    00225   std::cout << "Enter name, height (in cm),"
    00226                " and weight (in kg) for each person:\n";
    00227   while (get_record(names, heights, weights, sexes))
    00228   {
    00229     int bmi(compute_bmi(heights.back(), weights.back()));
    00230     bmis.push_back(bmi);
    00231     std::cout << "BMI = " << bmi << '\n';
    00232   }
    00233
    00234   // Print the data.
    00235   std::cout << "\n\nMale data\n";
    00236   print_table('M', heights, weights, bmis, sexes, names, threshold);
    00237   std::cout << "\nFemale data\n";
    00238   print_table('F', heights, weights, bmis, sexes, names, threshold);
    00239 }