Project 1 - Body-mass index

- Main Page
- Files

- File List
- File Members

bmi.cpp
Go to the documentation of this file.
1
39 #include <algorithm>
40 #include <cstdlib>
41 #include <iomanip>
42 #include <iostream>
43 #include <istream>
44 #include <limits>
45 #include <locale>
46 #include <ostream>
47 #include <string>
48 #include <vector>
49
60 int compute_bmi(int height, int weight)
61 {
62 return static_cast<int>(weight * 10000 / (height * height) + 0.5);
63 }
64
66 void skip_line()
67 {
68 std::cin.ignore(std::numeric_limits<int>::max(), '\n');
69 }
70
79 bool get_record(std::vector<std::string>& names,
80 std::vector<int>& heights,
81 std::vector<int>& weights,
82 std::vector<char>& sexes)
83 {
84 std::string name{};
85 int height{0};
86 int weight{0};
87 char sex{'?'};
88
89 std::cout << "Name " << names.size()+1 << ": ";
90 if (not std::getline(std::cin, name))
91 return false;
92
93 // Enforce minimal sanity check on the height, which must be
94 // between 10 and 300 cm, or baby- to giant-size.
95 int const min_height{10};
96 int const max_height{300};
97 std::cout << "Height (cm): ";
98 if (not (std::cin >> height))
99 return false;
100 skip_line();
101 if (height < min_height or height > max_height)
102 {
103 std::cout << "Invalid height. Aborting.\n";
104 return false;
105 }
106
107 // Enforce minimal sanity check on the weight, which must
108 // be between premature-baby and giant size.
109 int const min_weight{1};
110 int const max_weight{500};
111 std::cout << "Weight (kg): ";
112 if (not (std::cin >> weight))
113 return false;
114 skip_line();
115 if (weight < min_weight or weight > max_weight)
116 {
117 std::cout << "Invalid weight. Aborting.\n";
118 return false;
119 }
120
121 std::cout << "Sex (M or F): ";
122 if (not (std::cin >> sex))
123 return false;
124 skip_line();
125 sex = std::toupper(sex, std::locale());
126 if (sex != 'M' and sex != 'F')
127 {
128 std::cout << "Invalid sex. Aborting.\n";
129 return false;
130 }
131
132 // All information has now been collected, so
133 // append it all to the respective vectors.
134 names.push_back(name);
135 heights.push_back(height);
136 weights.push_back(weight);
137 sexes.push_back(sex);
138
139 return true;
140 }
141
155 void print_table(char sex,
156 std::vector<int> const& heights,
157 std::vector<int> const& weights,
158 std::vector<int> const& bmis,
159 std::vector<char> const& sexes,
160 std::vector<std::string> const& names,
161 int threshold)
162 {
163 std::cout << "Ht(cm) Wt(kg) Sex BMI Name\n";
164
165 float bmi_sum(0);
166 long int bmi_count(0);
167 std::vector<int> tmpbmis; // store only the BMIs that are printed
168 // to compute the median
169 for (std::vector<int>::size_type i(0); i != heights.size(); ++i)
170 if (sexes.at(i) == sex)
171 {
172 bmi_sum = bmi_sum + bmis.at(i);
173 ++bmi_count;
174 tmpbmis.push_back(bmis.at(i));
175 std::cout << std::setw(6) << heights.at(i)
176 << std::setw(7) << weights.at(i)
177 << std::setw(3) << sexes.at(i)
178 << std::setw(6) << bmis.at(i);
179 if (bmis.at(i) >= threshold)
180 std::cout << '*';
181 else
182 std::cout << ' ';
183 std::cout << ' ' << names.at(i) << '\n';
184 }
185
186 // If the vectors are not empty, print basic statistics.
187 if (bmi_count != 0)
188 {
189 std::cout << "Mean BMI = "
190 << std::setprecision(1) << std::fixed << bmi_sum / bmi_count
191 << '\n';
192
193 // Median BMI is trickier. The easy way is to sort the
194 // array and pick out the middle item or items.
195 std::sort(tmpbmis.begin(), tmpbmis.end());
196 std::cout << "Median BMI = ";
197 // Index of median item.
198 int i(tmpbmis.size() / 2);
199 if (tmpbmis.size() % 2 == 0)
200 std::cout << (tmpbmis.at(i) + tmpbmis.at(i-1)) / 2.0 << '\n';
201 else
202 std::cout << tmpbmis.at(i) << '\n';
203 }
204 }
205
207 int main()
208 {
209 std::locale::global(std::locale{""});
210 std::cout.imbue(std::locale{});
211 std::cin.imbue(std::locale{});
212
213 std::vector<std::string> names{};
214 std::vector<int> heights{};
215 std::vector<int> weights{};
216 std::vector<char> sexes{};
217 std::vector<int> bmis{};
218 int threshold{};
219
220 std::cout << "Enter threshold BMI: ";
221 if (not (std::cin >> threshold))
222 return EXIT_FAILURE;
223 skip_line();
224
225 std::cout << "Enter name, height (in cm),"
226 " and weight (in kg) for each person:\n";
227 while (get_record(names, heights, weights, sexes))
228 {
229 int bmi{compute_bmi(heights.back(), weights.back())};
230 bmis.push_back(bmi);
231 std::cout << "BMI = " << bmi << '\n';
232 }
233
234 // Print the data.
235 std::cout << "\n\nMale data\n";
236 print_table('M', heights, weights, bmis, sexes, names, threshold);
237 std::cout << "\nFemale data\n";
238 print_table('F', heights, weights, bmis, sexes, names, threshold);
239 }
main
int main()
Main program to compute BMI.
Definition: bmi.cpp:207
skip_line
void skip_line()
Skip the rest of the input line.
Definition: bmi.cpp:66
print_table
void print_table(char sex, std::vector< int > const &heights, std::vector< int > const &weights, std::vector< int > const &bmis, std::vector< char > const &sexes, std::vector< std::string > const &names, int threshold)
Print a table. Print a table of height, weight, sex, BMI, and name. Print only records for which sex ...
Definition: bmi.cpp:155
compute_bmi
int compute_bmi(int height, int weight)
Compute the body-mass index (BMI). The height is in centimeters, so the computed value is off by 10...
Definition: bmi.cpp:60
get_record
bool get_record(std::vector< std::string > &names, std::vector< int > &heights, std::vector< int > &weights, std::vector< char > &sexes)
Get a single person&#39;s record. Store the name, height, weight, and sex in the supplied vectors...
Definition: bmi.cpp:79