Here is the code:
#include <iostream>
#include <fstream>
#include "Students.pb.h"
class IRepository {
virtual void Open() = 0; // binary decerialization
virtual void Save() = 0; // binary serialization
};
class IMethods {
virtual double GetAverageScore(const FullName& name) = 0;
virtual std::string GetAllInfo(const FullName& name) = 0;
virtual std::string GetAllInfo() = 0;
};
StudentsGroup group1;
class StudentGroup : public IRepository, public IMethods
{
public:
void Open() override
{
std::fstream in("D:\GeekBrains CPP\diff moments 7\studentsgroup.bin", std::ios_base::binary);
group1.ParseFromIstream(&in);
if (!group1.ParseFromIstream(&in))
{
std::cout << "Open error!" << std::endl;
}
}
void Save() override
{
std::fstream out("D:\GeekBrains CPP\diff moments 7\studentsgroup.bin", std::ios_base::binary);
group1.SerializeToOstream(&out);
}
double GetAverageScore(const FullName& name) override
{
int i = 0;
double average;
for (const auto& student : group1.sinfo())
{
if (student.sname().surname() == name.surname() && student.sname().name() == name.name())
{
std::cout << "Average score is: " << student.averagemark();
average = student.averagemark();
i++;
}
}
if (i == 0)
{
std::cout << "No such student has been found!" << std::endl;
}
else if (i >= 2)
{
std::cout << "There're more then 1 student with this surname!" << std::endl;
}
return average;
}
std::string GetAllInfo(const FullName& name) override
{
int i = 0;
for(const auto& student : group1.sinfo())
{
if (student.sname().surname() == name.surname() && student.sname().name() == name.name())
{
std::cout << "Full Name: " << student.sname().surname() << " " << student.sname().name() << " " << student.sname().patronymic() << \
" marks: " ;
for (auto mark : student.grade())
{
std::cout << mark << "";
}
std::cout << "average mark: " << student.averagemark();
i++;
}
}
if (i == 0)
{
std::cout << "No such student has been found!" << std::endl;
}
return {};
}
std::string GetAllInfo() override
{
for (const auto student : group1.sinfo())
{
std::cout << "Full Name: " << student.sname().surname() << " " << student.sname().name() << " " << student.sname().patronymic() << \
" marks: ";
for (auto mark : student.grade())
{
std::cout << mark << " ";
}
std::cout << "average mark: " << student.averagemark() << std::endl;
}
if (group1.sinfo_size() == 0)
{
std::cout << "There're no students in the group yet" << std::endl;
}
return {};
}
};
double average(const google::protobuf::RepeatedField<int32_t>& grades)
{
double s = 0;
for (const int& i : grades)
{
s += i;
}
return round((s / grades.size())*100)/100;
}
int main()
{
auto name1 = std::make_unique<FullName>();
name1->set_surname("Sergeev");
name1->set_name("Sergey");
name1->set_patronymic("Sergeevich");
auto student1 = std::make_unique<Student>();
student1->set_allocated_sname(name1.release());
student1->add_grade(5);
student1->add_grade(4);
student1->add_grade(4);
student1->set_averagemark(average(student1->grade()));
std::cout << student1->averagemark() << std::endl;
group1.mutable_sinfo()->AddAllocated(student1.release());
for (auto i : group1.sinfo())
{
std::cout << "Full Name: " << i.sname().surname() << " " << i.sname().name() << " " << i.sname().patronymic() << \
" marks: ";
for (auto mark : i.grade())
{
std::cout << mark << " ";
}
std::cout << "average mark: " << i.averagemark() << std::endl;
}
StudentGroup sg1;
sg1.GetAllInfo();
**sg1.GetAverageScore(student1->sname());**
}
and here is proto file:
syntax="proto3";
message FullName{
string Surname = 1;
string Name = 2;
optional string Patronymic = 3;
}
message Student{
FullName sName = 1;
repeated int32 Grade = 2;
double AverageMark = 3;
}
message StudentsGroup{
repeated Student sInfo = 1;
}
I have several issues I can't resolve:
inline const ::FullName& Student::_internal_sname() const {
const ::FullName* p = _impl_.sname_;
return p != nullptr ? *p : reinterpret_cast<const ::FullName&>(
::_FullName_default_instance_);
I'm new to programming so appreciate any help. Thanks!
student1
is a smart pointer and holds nullptr
after student1.release()
in
group1.mutable_sinfo()->AddAllocated(student1.release());
The student1
is owned by group1
since that moment. Call them
sg1.GetAverageScore(group1.sinfo(0).sname());
sg1.GetAllInfo(group1.sinfo(0).sname());