Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
Alexander Zhirov | fe51d0480d |
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* lesson_1.cpp
|
||||
*
|
||||
* Created on: 16 окт. 2021 г.
|
||||
* Author: alexander
|
||||
*/
|
||||
|
||||
#include "lesson_1.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
|
||||
/****************************
|
||||
* Person *
|
||||
****************************/
|
||||
|
||||
std::optional<std::string> getOptStr(std::string &s)
|
||||
{
|
||||
if (s == "")
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream &out, const Person &p)
|
||||
{
|
||||
out << std::setw(15) << p.firstname << std::setw(12) << p.lastname;
|
||||
|
||||
if (p.patronymic.has_value())
|
||||
{
|
||||
out << std::setw(17) << p.patronymic.value();
|
||||
}
|
||||
else
|
||||
{
|
||||
out << std::setw(18);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
bool operator<(const Person &p1, const Person &p2)
|
||||
{
|
||||
return tie(p1.firstname, p1.lastname, p1.patronymic) < tie(p2.firstname, p2.lastname, p2.patronymic);
|
||||
}
|
||||
|
||||
bool operator==(const Person &p1, const Person &p2)
|
||||
{
|
||||
return tie(p1.firstname, p1.lastname, p1.patronymic) == tie(p2.firstname, p2.lastname, p2.patronymic);
|
||||
}
|
||||
|
||||
/*********************************
|
||||
* PhoneNumber *
|
||||
*********************************/
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
std::optional<int> getOptInt(std::string &s)
|
||||
{
|
||||
if (s == "")
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return std::stoi(s);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream &out, const PhoneNumber &p)
|
||||
{
|
||||
out << std::setw(3) << '+' << p.country_code << '(' << p.city_code << ')' << p.number;
|
||||
|
||||
if (p.additional_number.has_value())
|
||||
{
|
||||
out << ' ' << p.additional_number.value();
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/*******************************
|
||||
* PhoneBook *
|
||||
*******************************/
|
||||
|
||||
PhoneBook::PhoneBook(std::istream &file)
|
||||
{
|
||||
if (!file)
|
||||
{
|
||||
std::cout << "Не удаётся открыть файл!" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (std::string line; std::getline(file, line);)
|
||||
{
|
||||
std::stringstream str(line);
|
||||
std::vector<std::string> rowData;
|
||||
|
||||
for (std::string s; getline(str, s, ';');)
|
||||
{
|
||||
rowData.push_back(s);
|
||||
}
|
||||
|
||||
std::pair<Person, PhoneNumber> entry;
|
||||
|
||||
for (size_t i = 0; i < rowData.size(); ++i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
entry.first.firstname = rowData[i];
|
||||
break;
|
||||
case 1:
|
||||
entry.first.lastname = rowData[i];
|
||||
break;
|
||||
case 2:
|
||||
entry.first.patronymic = getOptStr(rowData[i]);
|
||||
break;
|
||||
case 3:
|
||||
entry.second.country_code = stoi(rowData[i]);
|
||||
break;
|
||||
case 4:
|
||||
entry.second.city_code = stoi(rowData[i]);
|
||||
break;
|
||||
case 5:
|
||||
entry.second.number = rowData[i];
|
||||
break;
|
||||
case 6:
|
||||
entry.second.additional_number = getOptInt(rowData[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_data.push_back(entry);
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream &out, const PhoneBook &pb)
|
||||
{
|
||||
for (const auto& [first, second] : pb.m_data)
|
||||
{
|
||||
out << first << ' ' << second << std::endl;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void PhoneBook::SortByName()
|
||||
{
|
||||
sort(m_data.begin(), m_data.end(), [](const std::pair<Person, PhoneNumber> &lhs, const std::pair<Person, PhoneNumber> &rhs)
|
||||
{
|
||||
return lhs.first < rhs.first;
|
||||
});
|
||||
}
|
||||
|
||||
void PhoneBook::SortByPhone()
|
||||
{
|
||||
sort(m_data.begin(), m_data.end(), [](const std::pair<Person, PhoneNumber> &lhs, const std::pair<Person, PhoneNumber> &rhs)
|
||||
{
|
||||
return lhs.second < rhs.second;
|
||||
});
|
||||
}
|
||||
|
||||
std::pair<std::string, std::vector<PhoneNumber>> PhoneBook::GetPhoneNumber(const std::string &firstname)
|
||||
{
|
||||
std::vector<PhoneNumber> phoneNumbers;
|
||||
int count = 0;
|
||||
|
||||
for_each(m_data.begin(), m_data.end(), [&](const auto &entry)
|
||||
{
|
||||
if (entry.first.firstname == firstname)
|
||||
{
|
||||
phoneNumbers.push_back(entry.second);
|
||||
++count;
|
||||
}
|
||||
});
|
||||
|
||||
switch (count)
|
||||
{
|
||||
case 0:
|
||||
return { "not found", phoneNumbers };
|
||||
case 1:
|
||||
return { "", phoneNumbers };
|
||||
default:
|
||||
return { "found more than 1", phoneNumbers };
|
||||
}
|
||||
}
|
||||
|
||||
void PhoneBook::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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* lesson_1.hpp
|
||||
*
|
||||
* Created on: 16 окт. 2021 г.
|
||||
* Author: alexander
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* main.cpp
|
||||
*
|
||||
* Created on: 22 сент. 2021 г.
|
||||
* Author: alexander
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
|
||||
struct Person
|
||||
{
|
||||
std::string firstname;
|
||||
std::string lastname;
|
||||
std::optional<std::string> patronymic;
|
||||
};
|
||||
|
||||
struct PhoneNumber
|
||||
{
|
||||
int country_code;
|
||||
int city_code;
|
||||
std::string number;
|
||||
std::optional<int> additional_number;
|
||||
};
|
||||
|
||||
class PhoneBook
|
||||
{
|
||||
private:
|
||||
std::vector<std::pair<Person, PhoneNumber>> m_data;
|
||||
public:
|
||||
PhoneBook(std::istream &file);
|
||||
friend std::ostream& operator<<(std::ostream &out, const PhoneBook &pb);
|
||||
void SortByName();
|
||||
void SortByPhone();
|
||||
std::pair<std::string, std::vector<PhoneNumber>> GetPhoneNumber(const std::string &firstname);
|
||||
void ChangePhoneNumber(const Person &p, const PhoneNumber &pn);
|
||||
};
|
||||
|
||||
std::optional<std::string> getOptStr(std::string &s);
|
||||
std::ostream& operator<<(std::ostream &out, const Person &p);
|
||||
bool operator<(const Person &p1, const Person &p2);
|
||||
bool operator==(const Person &p1, const Person &p2);
|
||||
|
||||
bool operator<(const PhoneNumber &p1, const PhoneNumber &p2);
|
||||
std::optional<int> getOptInt(std::string &s);
|
||||
std::ostream& operator<<(std::ostream &out, const PhoneNumber &p);
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* main.cpp
|
||||
*
|
||||
* Created on: 16 окт. 2021 г.
|
||||
* Author: alexander
|
||||
*/
|
||||
|
||||
#include "lesson_1.hpp"
|
||||
#include "tests.hpp"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* tests.hpp
|
||||
*
|
||||
* Created on: 17 окт. 2021 г.
|
||||
* Author: alexander
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "lesson_1.hpp"
|
||||
|
||||
class TestBook: public testing::Test
|
||||
{
|
||||
protected:
|
||||
PhoneBook *book;
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
std::stringstream src_stream;
|
||||
src_stream << "Ivanov;Daniil;Maksimovich;7;366;7508887;;\n"
|
||||
<< "Aleksandrov;Georgii;;493;7637;6114861;;\n"
|
||||
<< "Aleksandrov;Andrey;Mikhailovich;7;247;1377660;5542;\n"
|
||||
<< "Markelov;Dmitrii;Vadimovich;19;7576;5734416;2;\n";
|
||||
|
||||
book = new PhoneBook(src_stream);
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
delete book;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(TestBook, GetPhoneNumber_notFound)
|
||||
{
|
||||
std::string lastname = "Egorov";
|
||||
|
||||
auto answer = book->GetPhoneNumber(lastname);
|
||||
EXPECT_EQ(std::get<0>(answer), "not found");
|
||||
}
|
||||
|
||||
TEST_F(TestBook, GetPhoneNumber_foundOne)
|
||||
{
|
||||
std::string lastname = "Ivanov";
|
||||
|
||||
auto answer = book->GetPhoneNumber(lastname);
|
||||
EXPECT_EQ(std::get<0>(answer), "");
|
||||
}
|
||||
|
||||
TEST_F(TestBook, GetPhoneNumber_foundMore)
|
||||
{
|
||||
std::string lastname = "Aleksandrov";
|
||||
|
||||
auto answer = book->GetPhoneNumber(lastname);
|
||||
EXPECT_EQ(std::get<0>(answer), "found more than 1");
|
||||
}
|
||||
|
||||
TEST_F(TestBook, GetPhoneNumber_empty)
|
||||
{
|
||||
std::string lastname = "";
|
||||
|
||||
auto answer = book->GetPhoneNumber(lastname);
|
||||
EXPECT_EQ(std::get<0>(answer), "not found");
|
||||
}
|
||||
|
||||
TEST_F(TestBook, ChangePhoneNumber)
|
||||
{
|
||||
std::string lastname = "Ivanov";
|
||||
|
||||
ASSERT_EQ(std::get<0>(book->GetPhoneNumber(lastname)).empty(), true);
|
||||
|
||||
PhoneNumber answer = std::get<1>(book->GetPhoneNumber(lastname))[0];
|
||||
EXPECT_EQ(answer.number, "7508887");
|
||||
|
||||
book->ChangePhoneNumber(Person { "Ivanov", "Daniil", "Maksimovich" }, PhoneNumber { 7, 123, "15344458", std::nullopt });
|
||||
|
||||
answer = std::get<1>(book->GetPhoneNumber(lastname))[0];
|
||||
EXPECT_EQ(answer.country_code, 7);
|
||||
EXPECT_EQ(answer.city_code, 123);
|
||||
EXPECT_EQ(answer.number, "15344458");
|
||||
EXPECT_EQ(answer.additional_number, std::nullopt);
|
||||
}
|
||||
|
||||
TEST_F(TestBook, sortByName)
|
||||
{
|
||||
std::stringstream src_stream;
|
||||
src_stream << " Aleksandrov Andrey Mikhailovich +7(247)1377660 5542\n"
|
||||
<< " Aleksandrov Georgii +493(7637)6114861\n"
|
||||
<< " Ivanov Daniil Maksimovich +7(366)7508887\n"
|
||||
<< " Markelov Dmitrii Vadimovich +19(7576)5734416 2\n";
|
||||
|
||||
book->SortByName();
|
||||
|
||||
std::stringstream dst_stream;
|
||||
dst_stream << *book;
|
||||
|
||||
while (!dst_stream.eof())
|
||||
{
|
||||
std::string str_src;
|
||||
std::string str_dst;
|
||||
|
||||
src_stream >> str_src ;
|
||||
dst_stream >> str_dst;
|
||||
|
||||
EXPECT_EQ(str_dst, str_src);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TestBook, sortByPhone)
|
||||
{
|
||||
std::stringstream src_stream;
|
||||
src_stream << " Aleksandrov Andrey Mikhailovich +7(247)1377660 5542\n"
|
||||
<< " Ivanov Daniil Maksimovich +7(366)7508887\n"
|
||||
<< " Markelov Dmitrii Vadimovich +19(7576)5734416 2\n"
|
||||
<< " Aleksandrov Georgii +493(7637)6114861\n";
|
||||
|
||||
book->SortByPhone();
|
||||
|
||||
std::stringstream dst_stream;
|
||||
dst_stream << *book;
|
||||
|
||||
while (!dst_stream.eof())
|
||||
{
|
||||
std::string str_src;
|
||||
std::string str_dst;
|
||||
|
||||
src_stream >> str_src ;
|
||||
dst_stream >> str_dst;
|
||||
|
||||
EXPECT_EQ(str_dst, str_src);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue