How to pass Dynamic array of structures in c++? - c++

I have created an array dynamically of structures and now i am willing to pass it to function.What is the correct method of doing it?What should i put in parameter of function in MAIN for doing it?
void function(Data *family)
{
//code
}
int main()
{
struct Data{
string name;
int age;
string dob;
};
Data *family = new Data[3];
function(Data); //ERROR in parameter i guess!
}

It is better to use more safe ways using std::vector or std::shared_ptr. Because it is easy to make a mistake when you use raw pointers.
If you really need to use raw pointer than you need fix your code:
#include <string>
#include <iostream>
// "Data" should be declared before declaration of "function" where "Data" is used as parameter
struct Data {
std::string name;
int age;
std::string dob;
};
void function(Data *family)
{
std::cout << "function called\n";
}
int main()
{
Data *family = new Data[3];
// fill all variables of array by valid data
function(family); // Pass variable "family" but not a type "Data"
delete[] family; // DON'T FORGET TO FREE RESOURCES
return 0; // Return a code to operating system according to program state
}

Every c++ programmer needs to learn std::vector, which is a dynamic array:
#include <vector>
struct Data{
string name;
int age;
string dob;
};
void function(const std::vector<Data>& family)
{
//code
}
int main()
{
auto family = std::vector<Data>(3);//family now contains 3 default constructed Data
function(family);
}

Not sure what actually what actually you are looking for, I guess you can try like this:
First define your structure outside from main so it would be accessible as function parameter. Then instead of Data pass object family to the function.
struct Data {
string name;
int age;
string dob;
};
void function(Data *family)
{
//code
}
int main()
{
Data *family = new Data[3];
function(family);
}

Related

Manipulating vectors inside class methods

I just started learning about vectors, and they seem really handy, if talking about lists from a file. But I'm having a problem while trying to return a new vector from a class method and put it to another method of the same class.
i.e.
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
class A
{
public:
string name;
string age;
};
class Test
{
string name;
string age;
public:
void get(vector<A> students)
{
vector<A> specificStudents;
//rewrite a couple of students from vector<A>students
//to vector<A> specificStudents
};
void set(vector<A> specificStudents)
{
//I need to get vector<A> specificStudents here
};
};
int main()
{
vector<A> students;
A stud;
ifstream file("file.txt");
for (int i = 0; i < file.eof(); i++)
{
getline(file, stud.name);
getline(file, stud.age);
students.push_back(stud);
};
Test test;
test.get(students);
return 0;
}
Can I return it as a function argument?
It is not entirely clear, but do you want to save a copy of students inside test?:
class Test
{
vector<A> specificStudents;
public:
const vector<A>& get() const
{
return specificStudents;
}
void set(const vector<A>& students)
{
specificStudents = students;
// maybe modify `specificStudents` here in some way or assign it differently
}
};
int main()
{
vector<A> students;
A stud;
ifstream file("file.txt");
while (getline(file, stud.name) && getline(file, stud.age))
{
students.push_back(stud);
}
Test test;
test.set(students);
//... Do something with test
return 0;
}
If you don't know yet what & and const mean in this, you can just remove them (until you learn about them).
You seem to have gotten get and set mixed up. By usual convention, get gets something stored in the class object to the caller and set sets something in the class object (with a value provided by the caller).
I also fixed your input loop. I don't know what you thought file.eof() does, but comparing to i does not do anything useful.
Also be aware of where ; belongs and where it doesn't. It belongs after single statements and class definitions, but not after } of function definitions or other statement blocks, such as the one of while.
YES, you can return vector from a function.
To do this you can write a function like this one:
std::vector<A> get(vector<A> students)
and the inside it return the vector. An example can be:
vector<A> get(vector<A> students)
{
vector<A> specificStudents;
//rewrite a couple of students from vector<A>students
//to vector<A> specificStudents
return specificStudents;
};

How to initialize a structure variable to default values?

I am learning about structures now and I am trying to create default values for each variable of that structure type. My testing code is as follows:
#include<iostream>
using namespace std;
int main (void){
// DECLARING THE STRUCTURE
struct str_client{
char name[20] = "\0";
int age = 0;
double money = 0.00;
};
// DECLARING A VARIABLE OF THAT STRUCTURE TYPE (IN THIS CASE, AN ARRAY).
str_client client[3];
return (0);}
Is this initialization the correct way to do it?
Use constructor.
Since class and struct are similar.
struct str_client{
string name;
int age;
double money;
str_client()
{
name = "";
age = 0;
money = 0.0;
}
};
Edit
Using Member Initializer list will improve performance
struct str_client{
string name;
int age;
double money;
str_client()
: name(""), age(0), money(0.0)
{
}
};

naming objects by variables

I am in a situation that I need to make objects in runtime that are named by value of a string, but I can't do that:
cin>>input;
className "input"= new className;
How can I do that?
I think it is possible to achieve by using maps. Is it true?
As you said, you can achieve your goal by using std::map (or std::unordered_map)
map<string, className*> aMap;//map a string to a className pointer/address
cin>>input;
aMap[input] = new className; //input is mapped to a className pointer
Then you can treat aMap[input] as a className*. e.g.
To call a className method, you can:
aMap[input]->aClassNameMethod();
The object oriented way would be to make name a member of that class and use the input to construct the class.
#include <string>
#include <iostream>
class Foo
{
std::string myName;
public:
// Constructor assigning name to myName.
Foo(const std::string name) : myName(name) {}
std::string GetMyName() const
{
return myName;
}
};
int main()
{
std::string input;
std::cin >> input;
Foo f(input);
std::cout << f.GetMyName();
}
Also read about new in C++: Why should C++ programmers minimize use of 'new'?

c++ 2 Constructor 1 Object, How to?

I have to set up an object and, after an user chose, i have to change some param into the object but not every each.
example:
{
class Champ
{
private:
int hp;
std::string class;
public:
Champ();
Champ(std::string chose);
};
Champ::Champ() {hp=10; class="";}
Champ::Champ(std::string chose) {class = chose;}
main()
{
Champ Test;
std::string chose;
getline(cin,chose);
Test(chose);
return 0;
}
this code give me an error.
i need hp equal for all "Champ" created but class can be changed.
The hp can't be "const" because this value may undergo changes...
how can i do this? :/
The comments in the code below should explain what is going on well enough...
#include <iostream>
#include <string>
class Champ {
int hp;
std::string job;
public:
Champ():
hp(10) { } // don't need to explicitly initialize `job` because the default constructor for string does what we want.
explicit Champ(const std::string& choose):
hp(10),
job(choose) { }
};
int main(int argc, const char * argv[]) {
using namespace std;
// this is most like how you had it with the compile error fixed.
{
Champ test; // this creates a Champ object using the default constructor
string choose;
getline(cin, choose);
test = Champ(choose); // this creates a new Champ object and assigns it to test... Throwing away the one that was created earlier.
}
// this is, imho, a better way to do it:
{
string choose;
getline(cin, choose);
auto test = Champ(choose); // declare the variable as late as possible, and after you have all the data for its construction. That way, you only make one of them.
}
return 0;
}

How can I initialize char arrays in a constructor?

I'm having trouble declaring and initializing a char array. It always displays random characters. I created a smaller bit of code to show what I'm trying in my larger program:
class test
{
private:
char name[40];
int x;
public:
test();
void display()
{
std::cout<<name<<std::endl;
std::cin>>x;
}
};
test::test()
{
char name [] = "Standard";
}
int main()
{ test *test1 = new test;
test1->display();
}
And sorry if my formatting is bad, I can barely figure out this website let alone how to fix my code :(
If there are no particular reasons to not use std::string, do use std::string.
But if you really need to initialize that character array member, then:
#include <assert.h>
#include <iostream>
#include <string.h>
using namespace std;
class test
{
private:
char name[40];
int x;
public:
test();
void display() const
{
std::cout<<name<<std::endl;
}
};
test::test()
{
static char const nameData[] = "Standard";
assert( strlen( nameData ) < sizeof( name ) );
strcpy( name, nameData );
}
int main()
{
test().display();
}
Your constructor is not setting the member variable name, it's declaring a local variable. Once the local variable goes out of scope at the end of the constructor, it disappears. Meanwhile the member variable still isn't initialized and is filled with random garbage.
If you're going to use old-fashioned character arrays you'll also need to use an old-fashioned function like strcpy to copy into the member variable. If all you want to do is set it to an empty string you can initialize it with name[0] = 0.
Since you are using C++, I suggest using strings instead of char arrays. Otherwise you'd need to employ strcpy (or friends).
Also, you forgot to delete the test1 instance.
#include <iostream>
#include <string>
class test
{
private:
std::string name;
int x;
public:
test();
void display()
{
std::cout<<name<<std::endl;
}
};
test::test()
{
name = "Standard";
}
int main()
{
test test1;
test1.display();
std::cin>>x;
}
Considering you tagged the question as C++, you should use std::string:
#include <string>
class test
{
private:
std::string name;
int x;
public:
test();
void display()
{
std::cout<<name<<std::endl;
std::cin>>x;
}
};
test::test() : name("Standard")
{
}
c++11 actually provides two ways of doing this. You can default the member on it's declaration line or you can use the constructor initialization list.
Example of declaration line initialization:
class test1 {
char name[40] = "Standard";
public:
void display() { cout << name << endl; }
};
Example of constructor initialization:
class test2 {
char name[40];
public:
test2() : name("Standard") {};
void display() { cout << name << endl; }
};
You can see a live example of both of these here: http://ideone.com/zC8We9
My personal preference is to use the declaration line initialization because:
Where no other variables must be constructed this allows the generated default constructor to be used
Where multiple constructors are required this allows the variable to be initialized in only one place rather than in all the constructor initialization lists
Having said all this, using a char[] may be considered damaging as the generated default assignment operator, and copy/move constructors won't work. This can be solved by:
Making the member const
Using a char* (this won't work if the member will hold anything but a literal string)
In the general case std::string should be preferred