Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <fstream>
- #include <string>
- #include <vector>
- #include <algorithm>
- #include <iostream>
- #include <map>
- struct record_t {
- std::string name;
- std::string type;
- int year;
- int cost;
- int deaths;
- };
- std::ostream& operator<<(std::ostream& os, const record_t& record) {
- os << "Name: " << record.name << '\n'
- << "Type: " << record.type << '\n'
- << "Year: " << record.year << '\n'
- << "Cost: " << record.cost << '\n'
- << "Deaths: " << record.deaths << '\n';
- return os;
- }
- using records_t = std::vector<record_t>;
- records_t load() {
- std::ifstream f{"catastrophe.txt"};
- records_t records;
- std::string s;
- while (std::getline(f, s)) {
- record_t rec;
- auto it = s.begin();
- auto get_next = [&] {
- auto start = it;
- it = std::find(it, s.end(), ',');
- return std::string{ start, it++ };
- };
- auto trim_quotes = [](std::string s) { return s.substr(1, s.length() - 2); };
- rec.name = trim_quotes(get_next());
- rec.type = trim_quotes(get_next());
- rec.year = std::stoi(get_next());
- rec.cost = std::stof(get_next());
- rec.deaths = std::stoi(std::string{ it, s.end() });
- records.push_back(std::move(rec));
- }
- return records;
- }
- template <class Pred>
- void filter_and_display(const records_t& records, Pred pr) {
- bool seen_any = false;
- for (auto& record : records) {
- if (pr(record)) {
- seen_any = true;
- std::cout << record << '\n';
- std::cout << "********\n";
- }
- }
- if (!seen_any) {
- std::cout << "None found\n";
- }
- }
- void display_range(const records_t& records) {
- int start, end;
- std::cout << "Enter starting year: ";
- std::cin >> start;
- std::cout << "Enter ending year: ";
- std::cin >> end;
- if (start > end) {
- std::cout << "Error: End year < start year\n";
- return;
- }
- filter_and_display(records, [=](const record_t& record) {
- return record.year >= start && record.year < end;
- });
- }
- std::string to_lower(std::string s) {
- std::transform(s.begin(), s.end(), s.begin(), std::tolower);
- return s;
- }
- void search(const records_t& records) {
- std::cout << "Enter disaster: ";
- std::string disaster;
- std::cin >> disaster;
- disaster = to_lower(std::move(disaster));
- filter_and_display(records, [&](const record_t& record) {
- return to_lower(record.type) == disaster;
- });
- }
- void summary(const records_t& records) {
- struct totals_t {
- int disasters = 0;
- int deaths = 0;
- };
- std::map<int, totals_t> totals;
- for (const record_t& record : records) {
- auto& total = totals[record.year];
- total.disasters++;
- total.deaths += record.deaths;
- }
- std::ofstream os("report.txt");
- for (auto [year, total] : totals) {
- os << year << " - Disasters: " << total.disasters
- << " Deaths: " << total.deaths << '\n';
- }
- }
- int main() {
- auto records = load();
- bool quit = false;
- while (!quit) {
- std::cout << "1. Display all catastrophes in a year range\n";
- std::cout << "2. Search for a disaster\n";
- std::cout << "3. Summary report\n";
- std::cout << "4. Quit\n" << std::flush;
- int choice;
- std::cin >> choice;
- switch (choice) {
- case 1: display_range(records); break;
- case 2: search(records); break;
- case 3: summary(records); break;
- case 4: quit = true; break;
- default: std::cout << "Invalid choice\n"; break;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement