protobuf C++ issue with functions and double cout [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 months ago.
Improve this question
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:
When I cout averagemark with function GetAllInfo() or i.averagemark(), I get some rubbish but in case where I cout it as student1->averagemark() it worked well. How do I solve it?
I don't know how to enter arguments in functions double GetAverageScore(const FullName& name) override and std::string GetAllInfo(const FullName& name) override. Nothing I do seems to work. I get an exception:
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());

Related

Passing a variable through signal and slot system in Qt [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
So I want to pass a std::string variable through the signal and slot system in Qt; I have a class on heap called RecordTalks which emits a signal when received message from chat is longer than 25 signs.
The code is as follows:
#include "recordtalks.h"
// records chat to files RecordTalks::RecordTalks(QObject *parent) {
}
RecordTalks::~RecordTalks() {
std::cout << "destructor" << "\n"; }
void RecordTalks::run(QString data) {
std::cout << ">>> whole data is: " << data.toStdString() << " ------------------\n";
std::string text = data.toStdString();
extractNick(text);
extractRoom(text);
//std::cout << "save in recordTalks is: " << save << "\n";
if((nick.size()!=0 && room.size()!=0))
{
extractText(data);
pushToVector(removeDigitsAndSpecials(nick), subText);
}
else
return; }
void RecordTalks::run() {
save=false;
save = console.saveNowState();
if(save==true)
{
saveToFile(allTexts, "BOT"); //trigger line saving to file
file.close();
removeDuplicatedNicks();
createNickFiles(nicks_v);
match_nicks_and_allTexts(allTexts);
closeNickFiles();
nicks_v.clear();
nickAndFile_pair_vec.clear();
text.clear();
allTexts.clear();
nick.clear();
room.clear();
subText.clear();
save=false;
}
}
void RecordTalks::extractText(QString &data) {
std::string text = data.toStdString(); // tu zmiana
size_t pos, pos2;
if((pos=text.find("PRIVMSG #"))!=std::string::npos)
{
if((pos2=text.find(":",pos))!=std::string::npos)
{
subText = text.substr(pos2+1, text.size()-(pos2+1) );
if((pos=subText.find("\u0001ACTION "))!=std::string::npos)
{
subText = subText.substr(pos+8 , subText.size()-3-(pos+8));
}
else
std::cout << "subText: " << subText << "\n";
}
}
else //if nothing to write to log:
{
return ;
}
}
void RecordTalks::extractNick(std::string &text) {
Extract_NickAndRoom e;
QString temp = QString::fromStdString(text);
nick = e.extractNick(temp);
//std::cout << "nick is: " << nick << "\n";
}
void RecordTalks::extractRoom(std::string &text) {
Extract_NickAndRoom e;
QString temp = QString::fromStdString(text);
room = e.extractRoom(temp);
//std::cout << "room is: " << room << "\n"; }
void RecordTalks::pushToVector(std::string nick, std::string &subText)
//general vector with texts {
if(subText.size()>25 ) //if line of text from irc is bigger than 25 signs
{
std::pair<std::string, std::string> para = std::make_pair(nick, subText);
allTexts.push_back(para); // pair --> vector
emit textUpdateSignal(subText);
std::cout << "EMITTTTTTTTTTTTTTTTTTT " << "\n";
//std::cout << ">>> subText: " << subText << " nick: " << nick << " <<<" << "\n";
}
if(allTexts.size()==60)
{
saveToFile(allTexts, "BOT"); //trigger line saving to file
file.close();
removeDuplicatedNicks();
createNickFiles(nicks_v);
match_nicks_and_allTexts(allTexts);
closeNickFiles();
nicks_v.clear();
nickAndFile_pair_vec.clear();
text.clear();
allTexts.clear();
nick.clear();
room.clear();
subText.clear();
save=false;
}
}
void RecordTalks::saveToFile( std::vector< std::pair<std::string,
std::string> > &allTexts, std::string nickFileName) {
std::string address = "D:\\Qt_workspace\\weatherBot\\logs\\" + nickFileName + ".txt";
file.open(address, std::ios::out | std::ios::app);
for (int i = 0; i < allTexts.size(); ++i)
{
file << allTexts[i].second; //writes text to file, not the nicks
}
}
void RecordTalks::createNickFiles(std::vector<std::string> &nicks_v) {
/* make vector of pair nick and file, so we can identify the file name and then
put text-matching-to-file-nick with file name */
for (int i = 0; i < nicks_v.size(); ++i)
{
std::fstream file2("D:\\Qt_workspace\\weatherBot\\logs\\"+ nicks_v[i] + ".txt",
std::ios::out | std::ios::app);
std::pair<std::string, std::fstream> nickAndFile_pair;
nickAndFile_pair = std::make_pair(removeDigitsAndSpecials(nicks_v[i]),
std::move(file2));
nickAndFile_pair_vec.push_back(std::move(nickAndFile_pair));
}
}// nicks_v[i] put inside function removeDigitsAndSpecials(std::string& nick)
void RecordTalks::match_nicks_and_allTexts(std::vector<
std::pair<std::string, std::string> > allTexts) {
for (int i = 0; i < nickAndFile_pair_vec.size(); ++i)
{
for (int j = 0; j < allTexts.size(); ++j)
{
if(nickAndFile_pair_vec[i].first == allTexts[j].first)
{
nickAndFile_pair_vec[i].second << allTexts[j].second;
//nickAndFile_pair_vec[j].second.flush();
}
}
}
std::cout << "allTexts size in match_nicks_and_allTexts is: ";
std::cout << allTexts.size() << "\n";
}
void RecordTalks::removeDuplicatedNicks() {
std::vector< std::pair<std::string, std::string> > temp = allTexts;
std::cout << "temp size: " << temp.size() << "\n";
for (int i = 0; i < temp.size(); ++i)
{
for (int j = i+1; j < temp.size(); ++j)
{
if(temp[i].first == temp[j].first && i+1< temp.size())
{
temp.erase(temp.begin()+j);
j--;
}
}
}
for (int i = 0; i < temp.size(); ++i)
{
nicks_v.push_back(temp[i].first);
}
std::cout << "nicks_v.size: " << nicks_v.size() << "\n";
}
void RecordTalks::closeNickFiles() //closes separate nick files {
for (int i = 0; i < nickAndFile_pair_vec.size(); ++i)
{
nickAndFile_pair_vec[i].second.close();
}
std::cout << "Files closed..." << "\n"; }
std::string RecordTalks::removeDigitsAndSpecials(std::string& nick) {
for (int i = 0; i < nick.size(); ++i)
{
if(std::isalpha(nick[i]))
{
}
else if(std::isdigit(nick[i]))
{
nick.erase(nick.begin()+i);
std::cout << "removing: " << nick[i] << "\n";
i--;
}
else
{
nick.erase(nick.begin()+i);
std::cout << "removing: " << nick[i] << "\n";
i--;
}
}
return nick;
}
Then in another class i have the connect function. When i write it in this form:
connect(recordTalks, &RecordTalks::textUpdateSignal, this, &Socket::updateDatabaseSLOT);
the slot receives the signal. But when i write the function this way:
connect(recordTalks, SIGNAL(textUpdateSign(std::string)), this,
SLOT(updateDatabaseSLOT(std::string)));
the Slot is not fired. So my question is, what is the reason of that. In other cases the latter version works just fine.
The slot looks like this:
void Socket::updateDatabaseSLOT(std::string textUpdate)
{
std::cout << "updates text: << textUpdate << "\n";
database.push_back(textUpdate);
}
I think you have a typo in your connect statement. Qt can be frustrating that way. SIGNAL(textUpdateSign(std::string ) should probably be SIGNAL(textUpdateSignal(std::string ).

Class object will not push_back onto vector

Compiles and everything except adding in a 'ship'
Constructor for ship
Ship::Ship(std::string name, int length, std::string show) {
std::string _name = name;
int _length = length;
std::string _show = show;
}
void Ships::buildShip() {
std::string name, show;
int length = 0;
std::cout << "What is the name of the ship? ";
std::cin >> name;
std::cout << "How long is the ship in feet? ";
std::cin >> length;
std::cout << "What show/movie is the ship from? ";
std::cin >> show;
std::cout << std::endl;
Ship ship(name, length, show);
addShip(ship);
}
void Ships::addShip(Ship &ship) {
ships.push_back(ship);
}
I'm sure it's something very obvious, I've searched the web and found nothing helpful. I only took snippets from my code if anything else is needed let me know. Thanks in advance!
/Ship.h
#pragma once
#include <string>
class Ship {
std::string _name;
int _length;
std::string _show;
public:
Ship(){
std::string name = _name;
int length = _length;
std::string show = _show;
};
Ship(std::string _name, int _length, std::string _show);
std::string getName();
int getLength();
std::string getShow();
};
/Ship.cpp
#include <string>
#include "Ship.h"
Ship::Ship(std::string name, int length, std::string show) {
std::string _name = name;
int _length = length;
std::string _show = show;
}
std::string Ship::getName() {
return _name;
}
int Ship::getLength() {
return _length;
}
std::string Ship::getShow() {
return _show;
}
/Ships.h
#pragma once
#include <vector>
#include "Ship.h"
class Ships {
std::vector<Ship> ships;
public:
void addShip(Ship &ship);
int getCount();
Ship getLongestShip();
void buildShip();
int getNumberOfShipsLongerThan(int input);
void displayShips();
};
/Ships.cpp
#include "Ships.h"
#include <iostream>
void Ships::addShip(Ship &ship) {
ships.push_back(ship);
}
int Ships::getCount() {
return ships.size();
}
Ship Ships::getLongestShip() {
Ship longestShip = ships[0];
for (Ship aShip : ships) {
if (longestShip.getLength() < aShip.getLength())
longestShip = aShip;
}
std::cout << "The longest ship is the " << longestShip.getName() << std::endl;
std::cout << "From end to end the length is " << longestShip.getLength() << std::endl;
std::cout << "The show/movie it is from is " << longestShip.getShow() << std::endl;
return longestShip;
}
int Ships::getNumberOfShipsLongerThan(int input) {
int longerThan = 0;
int size = ships.size();
for (int i = 0; i < size; i++) {
if (input < ships[i].getLength())
longerThan++;
}
return longerThan;
}
void Ships::displayShips() {
std::cout << " Complete Bay Manifest " << std::endl;
std::cout << "***********************" << std::endl;
for (int i = 0; i < ships.size(); i++) {
int a = i + 1;
std::cout << "Ship (" << a << ")" << std::endl;
std::cout << "Name: " << ships[i].getName() << std::endl;
std::cout << "Length: " << ships[i].getLength() << std::endl;
std::cout << "Show: " << ships[i].getShow() << std::endl<<std::endl;
}
}
void Ships::buildShip() {
std::string name, show;
int length = 0;
std::cout << "What is the name of the ship? ";
std::cin >> name;
std::cout << "How long is the ship in feet? ";
std::cin >> length;
std::cout << "What show/movie is the ship from? ";
std::cin >> show;
std::cout << std::endl;
Ship ship(name, length, show);
addShip(ship);
}
/driver.cpp
#include <iostream>
#include "Ship.h"
#include "Ships.h"
void menu();
Ship buildShip();
void shipsInBay(Ships &ships);
void processDirective(int choice, Ships &ships);
void longerThan(Ships &ships);
int main() {
std::cout << "Welcome to Daniel Mikos' Ship Bay!" << std::endl << std::endl;
menu();
system("PAUSE");
return 0;
}
void menu() {
Ships ships;
int choice = 0;
std::cout << "Please make a selection" << std::endl;
std::cout << " (1) Add a ship to the bay" << std::endl;
std::cout << " (2) How many ships are already in the bay?" << std::endl;
std::cout << " (3) Which ship is the longest? " << std::endl;
std::cout << " (4) Ships longer than ___? " << std::endl;
std::cout << " (5) Manifest of all ships currently logged" << std::endl;
std::cout << " (6) Exit" << std::endl;
std::cout << " Choice: ";
std::cin >> choice;
processDirective(choice, ships);
}
Ship buildShip() {
std::string name, show;
int length = 0;
std::cout << "What is the name of the ship? ";
std::cin >> name;
std::cout << "How long is the ship in feet? ";
std::cin >> length;
std::cout << "What show/movie is the ship from? ";
std::cin >> show;
std::cout << std::endl;
Ship ship(name, length, show);
return ship;
}
void shipsInBay(Ships &ships) {
int count = ships.getCount();
std::cout << std::endl;
std::cout << "There is currently " << count;
std::cout << " ship(s) in bay" << std::endl << std::endl;
}
void longerThan(Ships &ships) {
int input = 0;
std::cout << "Find ships longer than? ";
std::cin >> input;
std::cout << "There are " << ships.getNumberOfShipsLongerThan(input) << "longer than " << input << "feet";
}
void processDirective(int choice, Ships &ships) {
if (choice == 1)
buildShip();
if (choice == 2)
shipsInBay(ships);
if (choice == 3)
ships.getLongestShip();
if (choice == 4)
longerThan(ships);
if (choice == 5)
ships.displayShips();
menu();
}
There is all of my code
To add an object to a vector of objects use emplace_back() and pass the constructor arguments as arguments to emplace back. It will then build the object in place so call:
ships.emplace_back(name, length, show);
to construct your ship object in place. Your constructor also is incorrect as pointed out by #Kevin. You need to change it to:
this->_name = name;
this->_length = length;
this->_show = show;
assuming I've guessed your class design correctly.
EDIT
Tried to build a minimum example from this and this works fine for me:
Header.h
class Ship {
std::string _name;
int _length;
std::string _show;
public:
Ship();
Ship(std::string _name, int _length, std::string _show);
std::string getName();
int getLength();
std::string getShow();
};
class Ships {
public:
void addShip(Ship &ship);
void buildShip();
std::vector<Ship> ships;
};
and Source.cpp
#include "Header.h"
Ship::Ship(std::string name, int length, std::string show) {
this->_name = name;
this->_length = length;
this->_show = show;
}
void Ships::buildShip() {
std::string name = "Name";
std::string show = "Show";
int length = 0;
ships.emplace_back(name, length, show);
}
int main(int argc, char argv[])
{
Ships ships;
ships.buildShip();
std::cout << "Number of ships = " << ships.ships.size() << std::endl;
return 0;
}
Prints Number of ships = 1. Can you slim it down to something like this?

Transform c++ class private variables to public

I am a first year student of programming, and I need some help.
I have code with public class but I need to change public to private. And it doesn't work for me. Maybe somebody can help me with some suggestions? Here's my working code with public objects, but I need to private. How can I do that?
This is my class's files:
Klientas.h:
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <iomanip>
using namespace std;
class Klientas
{
public:
string vardas;
double lesos;
};
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <iomanip>
using namespace std;
Klipas.h :
class Klipas
{
public:
string produktas;
string grupe;
double trukme;
double krastine1;
double krastine2;
double plotas;
double klipoSekKaina;
double klipoKaina;
};
My code:
Lab_1.cpp
#include "Klipas.h"
#include "Klientas.h"
using namespace std;
//---------------------------------------------
int main() {
setlocale(LC_ALL, "Lithuanian");
Klipas K[100];
int na;
Klientas kl;
// Iš failo fv įveda duomenis į objektų masyvą K(kiek).
ĮvestiDuomenis("Duomenys.txt", K, na);
SpausdintiDuomenis("Rezultatai.txt", K, na);
}
void ĮvestiDuomenis(string fv, Klipas K[], int & kiek) {
ifstream fd ("Duomenys.txt");
fd >> kiek;
fd.ignore();
for (int i = 0; i < kiek; i++) {
getline(fd, K[i].produktas, ','); fd >> ws;
fd >> K[i].grupe;
fd >> K[i].trukme;
fd >> K[i].krastine1;
fd >> K[i].krastine2;
fd >> K[i].klipoSekKaina;
fd.ignore();
}
fd.close();
// cout << "Programa baigė darbą\n";
}
// Objektų masyvo K(kiek) reikšmes spausdina lentele į failą fv
void SpausdintiDuomenis(string fv, Klipas K[], int kiek) {
ofstream fr("Rezultatai.txt", ios::app);
fr.setf(ios::fixed); fr.setf(ios::left);
cout << "Klipų skaičius: " << kiek << endl;
cout << "Klipų sąrašas:\n";
cout << "----------------------------------------------------\n";
cout << "| Produktas | Grupė | Klipo trukmė(s) | 1 Kraštinė(cm) | 2 Kraštinė(cm) | Klipo sekundės kaina(Eur/s) | \n";
cout << "----------------------------------------------------\n";
for (int i = 0; i < kiek; i++) {
cout << "| " << setw(10) << K[i].produktas << "| " << K[i].grupe
<< setprecision(0) << setw(10) << "| " << K[i].trukme << "| " << setw(15) << K[i].krastine1 << "| " << setw(10) << K[i].krastine2 << "| " << setw(10) << K[i].klipoSekKaina << endl;
}
{
cout << "-------------------------------\n";
cout << "Klipo Kava plotas:" << K[0].krastine1*K[0].krastine2 << " " << "cm2" << endl;
cout << "Klipo Obuolys plotas:" << K[1].krastine1*K[1].krastine2 << " " << "cm2" << endl;
cout << "Klipo Sultys plotas:" << K[2].krastine1*K[2].krastine2 << " " << "cm2" << endl;
cout << "-------------------------------\n";
}
string ilg_trukme; // randame kuris klipas yra ilgiausias
if (K[0].trukme > K[1].trukme) {
ilg_trukme = K[0].produktas;
} else if (K[1].trukme > K[2].trukme) {
ilg_trukme = K[1].produktas;
} else {
ilg_trukme = K[2].produktas;
}
cout << "Ilgiausias klipas: " << ilg_trukme << endl;
cout << "-------------------------------\n";
{
K[0].klipoKaina = K[0].trukme * K[0].klipoSekKaina;
K[1].klipoKaina = K[1].trukme * K[1].klipoSekKaina;
K[2].klipoKaina = K[2].trukme * K[2].klipoSekKaina;
cout << "Klipo Kava Kaina:" << K[0].klipoKaina << " " << "Eur." << endl;
cout << "Klipo Obuolys Kaina:" << K[1].klipoKaina << " " << "Eur." << endl;
cout << "Klipo Sultys Kaina:" << K[2].klipoKaina << " " << "Eur." << endl;
cout << "-------------------------------\n";
}
{
string brangiausias_klipas; //randame kuris klipas brangiausias
double br_kl;
Klientas kl;
if (K[0].klipoKaina > K[1].klipoKaina && K[0].klipoKaina > K[2].klipoKaina ) {
brangiausias_klipas = K[0].produktas;
br_kl = K[0].klipoKaina;
} else if (K[1].klipoKaina > K[2].klipoKaina) {
brangiausias_klipas = K[1].produktas;
br_kl = K[1].klipoKaina;
} else {
brangiausias_klipas = K[2].produktas;
br_kl = K[2].klipoKaina;
}
cout << "Brangiausias klipas yra: " << brangiausias_klipas << endl;
cout << "-------------------------------\n";
cout << "Kiek jūs turite pinigų? " << endl; //kliento turimos pajamos
cin >> kl.lesos ;
cout << "-------------------------------\n";
//Randame kuriuos klipus klientas glaėtų įsigyti su savo pajamom
{
if(kl.lesos < K[0].klipoKaina && kl.lesos < K[1].klipoKaina && kl.lesos < K[2].klipoKaina) {
cout << "Jūs negalite nusipikrti nei vieno klipo " << endl;
} else {
if(kl.lesos >= K[0].klipoKaina) {
cout << "Jūs galite nusipirkti klipą " << K[0].produktas << endl;
}
if (kl.lesos >= K[1].klipoKaina) {
cout << "Jūs galite nusipirkti klipą " << K[1].produktas << endl;
}
if (kl.lesos >= K[2].klipoKaina) {
cout << "Jūs galite nusipirkti klipą " << K[2].produktas << endl;
}
}
}
}
}
Your teacher probably wants you to use getters.
In:
class Klipas
{
public:
string produktas;
string grupe;
double trukme;
double krastine1;
double krastine2;
double plotas;
double klipoSekKaina;
double klipoKaina;
};
You want to have access to all these members, but prevent external changes.
So you can change your code to:
class Klipas
{
public:
string GetProduktas() {return produktas;}
string Getgrupe() {return grupe;}
double Gettrukme() {return trukme;}
double Getkrastine1() {return krastine1;}
double Getkrastine2() {return krastine2;}
double Getplotas() {return plotas;}
double GetklipoSekKaina(){return klipoSekKaina;}
double GetklipoKaina() {return klipoKaina;}
private:
string produktas;
string grupe;
double trukme;
double krastine1;
double krastine2;
double plotas;
double klipoSekKaina;
double klipoKaina;
};
and use those getters instead of the objects themselves in your function:
fd >> K[i].Getgrupe();
fd >> K[i].Gettrukme();
fd >> K[i].Getkrastine1();
fd >> K[i].Getkrastine2();
fd >> K[i].GetklipoKaina();
As for setters go, you can either set your values in the constructor, or implement the same way:
public:
void SetProduktas(string prdkt) {produktas = prdkt;}
You can rewrite your class variables to be private and then use getters and setters to modify them.
class C {
private:
int id;
public:
int get_id() { return this->id; }
void set_id(int newId) { this->id = newId; }
};
Or you can make private class inside of another class
class A {
private:
class D {};
};

The code is printing the same values when it should be randomly generating each ovr and also it is not printing the first value in the array

The issue that I am having is that with the code below, each plOvr for all of the class objects is the same. This causes them to have the same stats for everything. Also, I have an array with names that should be printed but it is skipping the first value.
using namespace std;
class Player
{
public:
int plOvr;
float plSpg, plSps;
string werk;
void setPlayeName(string);
string plName;
void setPlyrVal()
{
srand (time(NULL));
plOvr = rand()% 29 + 70;
plSps = plOvr / 10;
plSpg = plSps / 2;
}
};
void Player::setPlayeName(string werk)
{
plName = werk;
}
int main()
{
Player plyr1,plyr2,plyr3,plyr4,plyr5;
string firstTime;
string name[5] = {"Eric Gelinas","John Merill", "Jaromir Jagr", "Travis Zajac","Reid Boucher"};
bool firstOp;
cout << "Is this the first time this program has run?" << endl;
cin >> firstTime;
if (firstTime == "Yes" || firstTime == "yes")
{
firstOp == firstOp;
plyr1.setPlyrVal();
plyr1.setPlayeName(name[1]);
plyr2.setPlyrVal();
plyr2.setPlayeName(name[2]);
plyr3.setPlyrVal();
plyr3.setPlayeName(name[3]);
plyr4.setPlyrVal();
plyr4.setPlayeName(name[4]);
plyr5.setPlyrVal();
plyr5.setPlayeName(name[5]);
ofstream playerSaveData;
playerSaveData.open ("savedata.txt");
playerSaveData << plyr1.plName << "," << plyr1.plOvr << "," << plyr1.plSpg << "," << plyr1.plSps << "\n";
playerSaveData << plyr2.plName << "," << plyr2.plOvr << "," << plyr2.plSpg << "," << plyr2.plSps << "\n";
playerSaveData << plyr3.plName << "," << plyr3.plOvr << "," << plyr3.plSpg << "," << plyr3.plSps << "\n";
playerSaveData << plyr4.plName << "," << plyr4.plOvr << "," << plyr4.plSpg << "," << plyr4.plSps << "\n";
playerSaveData << plyr5.plName << "," << plyr5.plOvr << "," << plyr5.plSpg << "," << plyr5.plSps << "\n";
playerSaveData.close();
cout << "done.\n";
}
else
{
firstOp == !firstOp;
}
return 0;
}
You may use std::uniform_int_distribution<int> and an engine as std::mt19937 from <random>.
The engine (as srand) has to be initialized with seed only once.
Your program rewritten:
#include <ctime>
#include <iostream>
#include <fstream>
#include <string>
#include <random>
class Player
{
public:
void setPlayeName(const std::string& name) { plName = name; }
void setPlyrVal(std::mt19937& rand_engine)
{
std::uniform_int_distribution<int> distr(70, 98);
plOvr = distr(rand_engine);
plSps = plOvr / 10;
plSpg = plSps / 2;
}
public:
int plOvr;
float plSpg, plSps;
std::string werk;
std::string plName;
};
int main()
{
std::mt19937 rand_engine(time(nullptr));
Player plyrs[5];
const std::string names[5] = {"Eric Gelinas","John Merill", "Jaromir Jagr", "Travis Zajac","Reid Boucher"};
std::cout << "Is this the first time this program has run?" << std::endl;
std::string firstTime;
std::cin >> firstTime;
if (firstTime == "Yes" || firstTime == "yes") {
for (int i = 0; i != 5; ++i) {
plyrs[i].setPlyrVal(rand_engine);
plyrs[i].setPlayeName(names[i]);
}
std::ofstream playerSaveData;
playerSaveData.open ("savedata.txt");
for (const auto& plyr : plyrs) {
playerSaveData << plyr.plName << "," << plyr.plOvr << "," << plyr.plSpg << "," << plyr.plSps << "\n";
}
std::cout << "done." << std::endl;
}
return 0;
}
Live example
You should call srand() only once in the whole program, instead of calling it before each rand().

testing "Try and Catch"

In this program, I am using template class, I have a header file and this is my main file. I am having trouble displaying the (".....") IndexOutOfBounds and displaying it on the screen.
#include "XArray.h"
#include <iomanip>
#include <string>
using namespace std;
template<class T>
void afriend ( XArray<T> );
int main()
{
XArray<double> myAD(18);
myAD.randGen(15, 100);
cout << myAD.getType() << endl;
cout << setprecision(1) << fixed << "\n\n Unsorted: " << myAD;
myAD.sort();
cout << "\n Now Sorted: " << myAD;
cout << "\n\n";
**try
{
cout << "A[-5] = " << setw(6) << myAD[-5] << endl;
}
catch(XArray<double>::IndexOutOfBound e)
{
e.print();
}
try
{
cout << "A[8] = " << setw(6) << myAD[8] << endl;
}
catch(XArray<double>::IndexOutOfBound e)
{
e.print();
}**
cout << "\n\n" << setprecision(2) << fixed;
cout << "Size = " << setw(6) << myAD.getSize() << endl;
cout << "Mean = " << setw(6) << myAD.mean() << endl;
cout << "Median = " << setw(6) << myAD.median() << endl;
cout << "STD = " << setw(6) << myAD.std() << endl;
cout << "Min # = " << setw(6) << myAD.min() << endl;
cout << "Max # = " << setw(6) << myAD.max() << endl;
return 0;
}
There is the Array.h file posted as a dropbox link
Array.h
The code for operator[] in Array.h is:
template <class T>
T XArray<T>::operator[] (int idx)
{
if( (idx = 0) && (idx < size) )
{
return Array[idx];
}
else
{
throw IndexOutOfBound();
return numeric_limits<T>::epsilon();
}
}
Although the question is somewhat obscure, give a try to these suggestions.
Firstly, it can happen that XArray<>::IndexOutOfBounds have no proper copy ctor. You can try catching by const reference to workaround that:
try
{
...
}
catch(const XArray<double>::IndexOutOfBound& e)
{
e.print();
}
Index operator in standard library containers does not check for bounds, there is a special getter that does the check called at(). If the XArray class is designed with standard library in mind, it could behave similarly.
However to get more adequate response you need to be more specific describing the trouble you are having.
I'm still wondering what exact question is.
However, I'm understanding the question is that how I can use 'catch' by using 'IndexOutOfBound'.
#include <exception>
#include <iostream>
using namespace std;
template <typename T>
class Array
{
private:
int m_nLength;
T *m_ptData;
public:
...
...
T& operator[](int nIndex)
{
//assert(nIndex >= 0 && nIndex < m_nLength);
if(nIndex < 0 || nIndex > m_nLength)
{
throw myex;
}
else
{
return m_ptData[nIndex];
}
}
//class definition for 'IndexOutOfBound'
class IndexOutOfBound: public exception
{
public:
virtual const char* print() const throw()
{
return "Exception occured 'Index Out Of Bound'";
}
}myex;
};
int main()
{
Array<double> arr(3);
try
{
arr[0] = 1;
//exception will occur here.
arr[4] = 2;
}
catch(Array<double>::IndexOutOfBound &e)
{
cout << e.print() << '\n';
}
return 0;
}
Here is no 'XArray.h', so I've written a sample array class for example.
The problem is in the operator[] function. The code idx = 0 sets idx to 0. So all of your calls to operator[] will return the first element, and therefore there is no out-of-bounds error unless the array is empty.
You probably meant to write if ( idx >= 0 && idx < size ).
BTW the throw aborts the function, it makes no sense to return after throw.