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 }

Generated on Sun Nov 30 09:54:12 2008 for Project 1 - Body-mass index by  doxygen 1.5.3