geekbrains_cpp_difficult_mo.../lesson_1/main.cpp

263 lines
6.3 KiB
C++
Raw Normal View History

2021-09-24 01:04:01 +00:00
/*
* main.cpp
*
* Created on: 22 сент. 2021 г.
* Author: alexander
*/
#include <iostream>
#include <string>
#include <optional>
#include <vector>
#include <fstream>
#include <sstream>
2021-09-24 19:42:29 +00:00
#include <algorithm>
#include <iomanip>
2021-09-24 01:04:01 +00:00
using namespace std;
struct Person
{
string firstname;
string lastname;
2021-09-24 19:42:29 +00:00
optional<string> patronymic;
2021-09-24 01:04:01 +00:00
};
2021-09-24 19:42:29 +00:00
optional<string> getOptStr(string &s)
{
if (s == "")
2021-09-28 22:52:51 +00:00
{
2021-09-24 19:42:29 +00:00
return nullopt;
2021-09-28 22:52:51 +00:00
}
2021-09-24 19:42:29 +00:00
return s;
}
2021-09-24 01:04:01 +00:00
ostream& operator<<(ostream &out, const Person &p)
{
2021-09-24 19:42:29 +00:00
out << setw(15) << p.firstname << setw(12) << p.lastname;
if (p.patronymic.has_value())
{
out << setw(17) << p.patronymic.value();
}
else
{
out << setw(18);
}
2021-09-24 01:04:01 +00:00
return out;
}
bool operator<(const Person &p1, const Person &p2)
{
2021-09-28 22:52:51 +00:00
return tie(p1.firstname, p1.lastname, p1.patronymic) < tie(p2.firstname, p2.lastname, p2.patronymic);
2021-09-24 01:04:01 +00:00
}
bool operator==(const Person &p1, const Person &p2)
{
2021-09-28 22:52:51 +00:00
return tie(p1.firstname, p1.lastname, p1.patronymic) == tie(p2.firstname, p2.lastname, p2.patronymic);
2021-09-24 01:04:01 +00:00
}
struct PhoneNumber
{
int country_code;
int city_code;
string number;
2021-09-24 19:42:29 +00:00
optional<int> additional_number;
2021-09-24 01:04:01 +00:00
};
2021-09-28 22:52:51 +00:00
bool operator<(const PhoneNumber &p1, const PhoneNumber &p2)
{
return tie(p1.country_code, p1.city_code, p1.number, p1.additional_number) < tie(p2.country_code, p2.city_code, p2.number, p2.additional_number);
}
2021-09-24 19:42:29 +00:00
optional<int> getOptInt(string &s)
{
if (s == "")
2021-09-28 22:52:51 +00:00
{
2021-09-24 19:42:29 +00:00
return nullopt;
2021-09-28 22:52:51 +00:00
}
2021-09-24 19:42:29 +00:00
return stoi(s);
}
2021-09-24 01:04:01 +00:00
ostream& operator<<(ostream &out, const PhoneNumber &p)
{
2021-09-24 19:42:29 +00:00
out << setw(3) << '+' << p.country_code << '(' << p.city_code << ')' << p.number;
2021-09-24 01:04:01 +00:00
if (p.additional_number.has_value())
{
out << ' ' << p.additional_number.value();
}
return out;
}
class PhoneBook
{
private:
2021-09-24 19:42:29 +00:00
vector<pair<Person, PhoneNumber>> m_data;
2021-09-24 01:04:01 +00:00
public:
PhoneBook(ifstream &file)
{
if (!file)
{
cout << "Не удаётся открыть файл!" << endl;
exit(-1);
}
2021-09-24 19:42:29 +00:00
for (string line; getline(file, line);)
2021-09-24 01:04:01 +00:00
{
2021-09-24 19:42:29 +00:00
stringstream str(line);
vector<string> rowData;
2021-09-24 01:04:01 +00:00
2021-09-24 19:42:29 +00:00
for (string s; getline(str, s, ';');)
{
rowData.push_back(s);
}
2021-09-24 01:04:01 +00:00
pair<Person, PhoneNumber> entry;
2021-09-24 19:42:29 +00:00
for (size_t i = 0; i < rowData.size(); ++i)
2021-09-24 01:04:01 +00:00
{
switch (i)
{
case 0:
2021-09-24 19:42:29 +00:00
entry.first.firstname = rowData[i];
2021-09-24 01:04:01 +00:00
break;
case 1:
2021-09-24 19:42:29 +00:00
entry.first.lastname = rowData[i];
2021-09-24 01:04:01 +00:00
break;
case 2:
2021-09-24 19:42:29 +00:00
entry.first.patronymic = getOptStr(rowData[i]);
2021-09-24 01:04:01 +00:00
break;
case 3:
2021-09-24 19:42:29 +00:00
entry.second.country_code = stoi(rowData[i]);
2021-09-24 01:04:01 +00:00
break;
case 4:
2021-09-24 19:42:29 +00:00
entry.second.city_code = stoi(rowData[i]);
2021-09-24 01:04:01 +00:00
break;
case 5:
2021-09-24 19:42:29 +00:00
entry.second.number = rowData[i];
2021-09-24 01:04:01 +00:00
break;
case 6:
2021-09-24 19:42:29 +00:00
entry.second.additional_number = getOptInt(rowData[i]);
2021-09-24 01:04:01 +00:00
break;
}
}
m_data.push_back(entry);
}
}
2021-09-24 19:42:29 +00:00
friend ostream& operator<<(ostream &out, const PhoneBook &pb)
{
for (const auto& [first, second] : pb.m_data)
{
out << first << ' ' << second << endl;
}
2021-09-24 01:04:01 +00:00
2021-09-24 19:42:29 +00:00
return out;
}
void SortByName()
2021-09-24 01:04:01 +00:00
{
2021-09-28 22:52:51 +00:00
sort(m_data.begin(), m_data.end(), [](const pair<Person, PhoneNumber> &lhs, const pair<Person, PhoneNumber> &rhs)
{
return lhs.first < rhs.first;
});
2021-09-24 01:04:01 +00:00
}
2021-09-24 19:42:29 +00:00
void SortByPhone()
{
2021-09-28 22:52:51 +00:00
sort(m_data.begin(), m_data.end(), [](const pair<Person, PhoneNumber> &lhs, const pair<Person, PhoneNumber> &rhs)
{
return lhs.second < rhs.second;
});
2021-09-24 19:42:29 +00:00
}
2021-09-28 22:52:51 +00:00
pair<string, vector<PhoneNumber>> GetPhoneNumber(const string &firstname)
2021-09-24 19:42:29 +00:00
{
2021-09-28 22:52:51 +00:00
vector<PhoneNumber> phoneNumbers;
2021-09-24 19:42:29 +00:00
int count = 0;
for_each(m_data.begin(), m_data.end(), [&](const auto &entry)
{
if (entry.first.firstname == firstname)
{
2021-09-28 22:52:51 +00:00
phoneNumbers.push_back(entry.second);
2021-09-24 19:42:29 +00:00
++count;
}
});
switch (count)
{
case 0:
2021-09-28 22:52:51 +00:00
return {"not found", phoneNumbers};
2021-09-24 19:42:29 +00:00
case 1:
2021-09-28 22:52:51 +00:00
return {"", phoneNumbers};
2021-09-24 19:42:29 +00:00
default:
2021-09-28 22:52:51 +00:00
return {"found more than 1", phoneNumbers};
2021-09-24 19:42:29 +00:00
}
}
void ChangePhoneNumber(const Person &p, const PhoneNumber &pn)
{
auto entry = find_if(m_data.begin(), m_data.end(), [&](const auto &entry)
{
return entry.first == p;
});
if (entry != m_data.end())
{
entry->second = pn;
}
}
};
2021-09-24 01:04:01 +00:00
int main()
{
ifstream file("PhoneBook.txt");
PhoneBook book(file);
cout << book;
2021-09-24 19:42:29 +00:00
cout << "------SortByPhone-------" << endl;
book.SortByPhone();
cout << book;
cout << "------SortByName--------" << endl;
book.SortByName();
cout << book;
cout << "-----GetPhoneNumber-----" << endl;
// лямбда функция, которая принимает фамилию и выводит номер телефона этого человека, либо строку с ошибкой
auto print_phone_number = [&book](const string &surname)
{
cout << surname << "\t";
auto answer = book.GetPhoneNumber(surname);
if (get<0>(answer).empty())
2021-09-28 22:52:51 +00:00
{
for (size_t i = 0; i < get<1>(answer).size(); ++i)
{
cout << get<1>(answer)[i];
}
}
2021-09-24 19:42:29 +00:00
else
2021-09-28 22:52:51 +00:00
{
cout << get<0>(answer);
}
2021-09-24 19:42:29 +00:00
cout << endl;
};
// вызовы лямбды
print_phone_number("Ivanov");
print_phone_number("Petrov");
cout << "----ChangePhoneNumber----" << endl;
2021-09-28 22:52:51 +00:00
book.ChangePhoneNumber(Person { "Kotov", "Vasilii", "Eliseevich" }, PhoneNumber { 7, 123, "15344458", nullopt });
book.ChangePhoneNumber(Person { "Mironova", "Margarita", "Vladimirovna" }, PhoneNumber { 16, 465, "9155448", 13 });
2021-09-24 19:42:29 +00:00
cout << book;
2021-09-24 01:04:01 +00:00
return 0;
}