i am trying pass a struct array from a function. i searched a lot but was unable to find a way to this. below is the code i am tring.
struct menuItemType
{
int itemNo;
string menuItem;
double price;
};
void getData(menuItemType *menuList[10])
{
menuList[0]->itemNo = 111;
menuList[0]->menuItem = "Apple";
menuList[0]->price = 2.00;
....
menuList[0]->itemNo = 120;
menuList[0]->menuItem = "Chocolate";
menuList[0]->price = 5.00;
}
int main()
{
/* i know that i can't return a array. but i want to get the menuList[10] values here.
not sure which code i have to use..*/
}
Your void getData(menuItemType *menuList[10]) does not return anything. Instead, it fills the data in the memory pointed by input parameter.
int main()
{
menuItemType data[10];
getData(&data);
std::cout << data[9].menuItem << std::endl; // Chocolate
}
However, why are you insisting on using low level arrays? Use std::vector instead.
std::vector<menuItemType> getData()
{
std::vector<menuItemType> data;
data.push_back({111, "Apple", 2.00});
...
data.push_back({120, "Chocolate", 5.00});
return std::move(data);
}
int main()
{
std::vector<menuItemType> data = getData();
std::cout << data[9].menuItem << std::endl; // Chocolate
}
It will print Chocolate, because I assume there is a typo in your code.
Related
I'm trying to run a code that its's meant to change the value of object variables after it creates the object, and it isn't changing, then the variable is returning values like -815470397 and not changing. And when I use breakpoints it's like it jumps the inside part of the setter.
Pessoa.h
#pragma once
using namespace std;
class Pessoa
{
protected:
int dia;
int mes;
int ano;
int idade;
public:
Pessoa();
Pessoa(int, int, int, int);
int GetDia();
void SetDia(int);
int GetMes();
void SetMes(int);
int GetAno();
void SetAno(int);
int GetIdade();
void SetIdade(int);
};
Pessoa.cpp
#include "Pessoa.h"
Pessoa::Pessoa() {
}
Pessoa::Pessoa(int dia, int mes, int ano, int idade) {
this->dia = dia;
this->mes = mes;
this->ano = ano;
this->idade = idade;
}
int Pessoa::GetDia() {
return this->dia;
}
int Pessoa::GetMes() {
return this->mes;
}
int Pessoa::GetAno() {
return this->ano;
}
int Pessoa::GetIdade() {
return this->idade;
}
void Pessoa::SetDia(int dia) {
this->dia == dia;
}
void Pessoa::SetMes(int mes) {
this->mes == mes;
}
void Pessoa::SetAno(int ano) {
this->ano == ano;
}
void Pessoa::SetIdade(int idade) {
this->idade == idade;
}
Exame_especial.cpp
#include <iostream>
#include <string>
#include "Pessoa.h"
using namespace std;
string ImprimeIdade(Pessoa*);
int Calc_Idade(Pessoa*, int, int, int);
int main()
{
Pessoa* Einstein = new Pessoa();
Pessoa* Newton = new Pessoa();
Einstein->SetDia(14);
Einstein->SetMes(3);
Einstein->SetAno(1879);
Newton->SetDia(4);
Newton->SetMes(1);
Newton->SetAno(1643);
cout << ImprimeIdade(Newton) << endl;
cout << ImprimeIdade(Einstein) << endl;
}
string ImprimeIdade(Pessoa* nome) {
nome->SetIdade(Calc_Idade(nome, 29, 6, 2021));
return "A idade de Einstein seria " + to_string(nome->GetIdade()) + "\n";
}
int Calc_Idade(Pessoa* nome, int dia, int mes, int ano) {
int idade = ano - nome->GetAno();
if (nome->GetMes() > mes) {
idade = idade - 1;
}
else {
if (nome->GetMes() == mes) {
if (nome->GetDia() > dia) {
idade = idade - 1;
}
}
}
return idade;
}
You get these strange values due to the fact that your data members are of built-in type and they remain uninitialized when you use them. They remain uninitialized because your setters aren't setting anything. What they actually do is a comparison (the ==).
Pay attention to the difference in these two:
void Pessoa::SetDia(int dia) {
this->dia == dia; // Equal? Returns bool value which is lost
}
Vs
void Pessoa::SetDia(int new_dia) {
this->dia = new_dia; // Assigns a new value
}
This goes for all setters in your code.
Also, note that inside the body of a member function, you can refer to the data members directly, without the need to dereference them via this:
void Pessoa::SetDia(int new_dia) {
// Assigns new value to the dia data member of this
dia = new_dia;
}
i have these set and get methods declared in my main cpp file
void issuesofRelevance::setApproach(int Approach) {
approach = Approach;
}
int issuesofRelevance::getApproach() {
return approach;
}
void issuesofRelevance::setSignifiance(int Significance) {
significance = Significance;
}
int issuesofRelevance::getSignificance() {
return significance;
}
The following H file is attatched in which I call the setMethods in its constructor.
class issuesofRelevance
{
public:
std::vector<std::string> issueName;
int significance;
int approach;
std::vector<std::string> newList;
issuesofRelevance(std::vector<std::string> issueName, int significance, int approach){
issueName = issueName;
significance = significance;
approach = approach;
setApproach(15);
setSignifiance(15);
}
issuesofRelevance();
void setIssues();
std::string getIssues();
void setApproach(int x);
void setSignifiance(int);
int getApproach();
int getSignificance();
};
I call the get functions in main int() as such
cout << object.getApproach();
cout << object.getSignificance();
However, when i go to run the code in the console I get no output when it should return the values of 10 and 15. Im unsure as to why this is occuring
Thankyou.
my full main as requested
int main(int argc, char* argv[]) { //takes in n, number of electorates, and m, the number of campagian days
issuesofRelevance newIssues(newIssues.issueName, newIssues.significance, newIssues.approach);
return 0;
Party party;
Person person;
Electrorates electorate;
string numberofElectoratesAsString = argv[1]; //number of electorates taking as a argument
string DaysOfElectionAsString = argv[2]; //takes in argument 2
int numberofElectorates = std::stoi(numberofElectoratesAsString);
int DaysOfElection = std::stoi(DaysOfElectionAsString );
cout << "Number of electorates: " << electorate.assignID(electorate.numberofElectorates(numberofElectorates));
cout << "Stance: " << person.setinitalStance(numberofElectorates, DaysOfElection) << endl;
newIssues.setIssues();
cout<<newIssues.getApproach()<< " "<<newIssues.getSignificance();
return 0;
}
default constructor
issuesofRelevance::issuesofRelevance(){
}
If we have a vector of struct pointer MyInfo* (allocated on heap). Then we can check vec[i] == NULL to know whether there is a struct in the vec[i], like this, if (vec[i] != NULL) //then do some processing
However, if we allocate MyInfo on stack instead of on heap, then we have vector<MyInfo> as shown below. I guess each vec[i] is initialized by the struct default constructor. How do you check whether vec[i] contains a non-empty struct similar to above NULL pointer case, like if (vec[i] contains valid struct) //then do some processing
My code is below
#include <iostream> // std::cout
#include <string>
#include <vector>
using namespace std;
struct MyInfo {
string name;
int age;
};
int main () {
vector<MyInfo> vec(5);
cout << "vec.size(): " << vec.size() << endl;
auto x = vec[0];
cout << x.name << endl; //this print "" empty string
cout << x.age << endl; //this print 0
return 0;
}
There are some options you can use. The first and easiest one, is to define a value to each (or for one) of your struct's variables, that will point that the struct is not initialized yet. In this case, age should be large or equal to 0, to be logicly straight. So, you can initialize it to -1, like this:
struct MyInfo {
string name;
int age = -1;
};
// Or
struct MyInfo {
string name;
int age;
MyInfo() : name(""), age(-1) {} // Use constructor
};
Now, in your main function, it will print in the age the value -1. Also, you can see the empty of the name variable as a sign for it too.
Another way might be using flag and get/set operations to indicate when the variables are initialize:
struct MyInfo {
private:
std::string _name;
int _age;
bool age_initialize = false;
bool name_initialize = false;
public:
void name(const std::string &name_p) { _name = name_p; name_initialize = true; }
void age(int age_p) { _age = age_p; age_initialize = true; }
void init(int age_p, const std::string &name_p) { age(age_p); name(name_p); }
bool is_initialize() { return name_initialize && age_initialize; }
int age() { return _age; }
std::string name() { return _name; }
};
int main() {
std::vector<MyInfo> vec(5);
std::cout << "vec.size(): " << vec.size() << std::endl;
auto x = vec[0];
std::cout << x.is_initialize() << std::endl; //this print 0
std::cout << x.name() << std::endl; //this print "" empty string
std::cout << x.age() << std::endl; //this print 0
return 0;
}
You can also throw an exception when calling int age() of std::string name() function, if those values are not initialize yet:
struct MyInfo {
private:
/* ... */
public:
/* ... */
int age() {
if (!age_initialize) throw std::runtime_error("Please initialize age first.");
return _age;
}
std::string name() {
if (!name_initialize) throw std::runtime_error("Please initialize name first.");
return _name;
}
};
I am a beginner in C++. I am working on inheritance. I have written a code and compiled it and it seems to be working fine and I am getting the expected output. But when I compile it, I get 13 similar warnings. I am not sure what is the problem? How can I override these warnings? Here is my code:
#include <iostream>
#include <string.h>
using namespace std;
class Identity
{
protected:
char *name;
int dob;
char* blood_group;
Identity(char *iname="", int nlength=1, int idob=0, char *iblood_group="", int blength=2):dob(idob)
{
name = new char[nlength+1];
strncpy(name,iname,nlength);
name[nlength]='\0';
blood_group = new char[blength+1];
strncpy(blood_group,iblood_group,blength);
blood_group[blength]='\0';
}
~Identity()
{
delete[] name;
delete[] blood_group;
}
};
class Physical
{
protected:
double height;
double weight;
Physical(double pheight = 0.0, double pweight = 0.0):height(pheight),weight(pweight)
{
}
};
class Registration
{
protected:
int policy_number;
char* contact_address;
Registration(int p_num=0, char* addr="", int alength=1):policy_number(p_num)
{
contact_address = new char[alength+1];
strncpy(contact_address,addr,alength);
contact_address[alength] = '\0';
}
~Registration()
{
delete[] contact_address;
}
};
class Contact:public Identity, public Physical, public Registration
{
private:
char* ph_number;
char* driver_license;
public:
Contact(char *name ="",int nlength=0,int dob = 0, char* blood = "", int blength = 0,double height = 0, double weight = 0, int pol_num = 0, char* cont_addr="", int alength=10, char *ph="",int plength=10,char* lic="",int llength=10):Identity(name,nlength,dob,blood,blength),Physical(height,weight), Registration(pol_num,cont_addr,alength), ph_number(ph),driver_license(lic)
{
ph_number = new char[plength+1];
strncpy(ph_number,ph,plength);
ph_number[plength] = '\0';
driver_license = new char[llength+1];
strncpy(driver_license,lic,llength);
driver_license[llength] = '\0';
}
~Contact()
{
delete[] ph_number;
delete[] driver_license;
}
char* GetName()
{
return name;
}
int GetDob()
{
return dob;
}
char* GetBloodGroup()
{
return blood_group;
}
double GetHeight()
{
return height;
}
double GetWeight()
{
return weight;
}
int GetPolicyNum()
{
return policy_number;
}
char* GetAddress()
{
return contact_address;
}
char* GetPhoneNumber()
{
return ph_number;
}
char* GetDriverLicense()
{
return driver_license;
}
};
int main()
{
using namespace std;
Contact kck("MyName",strlen("MyName"),11111111,"A+",strlen("A+"),15.10,651.5,1111,"MyArea",strlen("MyArea"),"1111111111", strlen("1111111111"),"ABCD1234",strlen("ABCD1234"));
cout << kck.GetName() << endl;
cout << kck.GetDob() << endl;
cout << kck.GetBloodGroup() << endl;
cout << kck.GetHeight() << endl;
cout << kck.GetWeight() << endl;
cout << kck.GetPolicyNum() << endl;
cout << kck.GetAddress() << endl;
cout << kck.GetPhoneNumber() << endl;
cout << kck.GetDriverLicense() << endl;
return 0;
}
In many places you write things like:
char *name = ""
However, "" has type const char[1] . This implicitly converts to const char *. But then you try to assign it to a char *, which is an attempt to ignore the const qualifier.
Since C++11 this is not allowed at all. Before C++11 this was allowed but deprecated. The compiler is warning you that it's a bad idea.
If you really must use pointers, then use char const * for any situation where you might be pointing to a string literal.
But you would be far better off avoiding the use of pointers entirely, as they complicate your code and introduce the opportunity for errors where there would be none if you hadn't used pointers. Passing the length of your strings separately from the string is extremely bad.
For example, use string to hold all of your strings. As a beginner, it would be good to begin with the easiest technique, which coincidentally is also the best technique. The way you have written your program so far is just making life difficult for yourself for no reason.
class test
{
private:
string *firstname;
public:
void setfname(const string fname[])
{
delete[] firstname;
firstname = new string[3];
for (int i = 0; i < 3; i++)
{
firstname[i] = fname[i];
}
}
string* getfname(const string fname[]) const
{
return firstname;
}
};
ok now I know the return function is wrong because it's giving me direct access, how do i set up the function so it doesn't allow it.
This is how I am going to test it:
int main()
{
test t;
string narray[3] = { "Name1", "Name2", "Name3" };
t.setfname(narray);
cout << "\nAfter t.setfname(narray);"
<< "\nf.getfname(narray) follows: ";
cout << t.getfname(narray);
}
I know getfname is wrong, how do I fix it?
In the simplest case, just return a copy of the string instead of a pointer:
string getfname(const string fname[]) const
{
return *firstname;
}
Even better, store a string instead of a pointer to it:
class test
{
private:
string firstname;
...