String in struct in struct in C++ - c++

So I've to do another exercise. This time I need to define a struct and a 100-elements array, which will store information about the book (title, author, ID number, price) and a simple function which will print info about all of the books stored. I started with that code:
#include <iostream>
using namespace std;
int main()
{
struct name_surname {string name, surname;};
struct book {string title; name_surname author_name, author_surname; int ID; int price;};
return 0;
}
And, well, what now? How can I store this in an array?

You just create an array of type book or name_surname or whatever you want.
Example:
book arr[100];
arr[0].title = "The last robot";
arr[0].ID = 2753;
Tips:
It's good programming practice if your structs/classes begin with with capital letter, so it's easier to distinguish them and so it is easier to name the variable the same name just without the capital letter. Example.
struct Name_surname
{
string name, surname;
};
Name_surname name_surname[100];
name_surname[0].name = "MyName";
Another tip is that I'd really suggest you learn how to research, this question has been answered millions of times and answers are all over the internet.

Here is my suggestion :
struct book
{
string title;
string name_surname;
string author_name;
string author_surname;
int ID;
int price;
};
struct Database
{
book *array;
void printDatabase()
{
for(int i = 0 ; i < 100 ;i++)
cout<<array[i].title<<endl;
}
Database()
{
array = new string [100];
}
};

Your name structure seems a little confused but creating an array is simply a case of declaring a variable with [] appended to it giving the size.
For example:
struct full_name
{
std::string firstname;
std::string surname;
};
struct book
{
std::string title;
full_name author;
int ID;
int price;
};
int main()
{
// Declare an array using []
book books[100]; // 100 book objects
// access elements of the array using [n]
// where n = 0 - 99
books[0].ID = 1;
books[0].title = "Learn To Program In 21 years";
books[0].author.firstname = "Idont";
books[0].author.surname = "Getoutalot";
}

What do you think about that:
#include <iostream>
using namespace std;
struct book {string title; string name; int ID; int price;} tab[100];
void input(book[]);
void print(book[]);
int main()
{
input(tab);
print (tab);
return 0;
}
void input(book tab[])
{
for (int i=0;i<3;i++)
{
cout<<"\nBook number: "<<i+1<<endl;
cout<<"title: ";cin>>tab[i].title;
cout<<"name: ";cin>>tab[i].name;
cout<<"ID: ";cin>>tab[i].ID;
cout<<"price: ";cin>>tab[i].price;
}
}
void print (book tab[])
{
for (int i=0; i<3; i++)
{
cout<<"\nBook number: "<<i+1<<endl;
cout<<"title: "<<tab[i].title;
cout<<"\nname: "<<tab[i].name;
cout<<"\nID: "<<tab[i].ID;
cout<<"\nprice: \n"<<tab[i].price;
}
}
I've done this with help from some Yt video. It works, but, is there a way to do it better, or just leave it how it is? And I have a question: Why those function parameters? Can't I just say tab[] or something else?

Computer languages are based on general and recursive rules. Just try to experiment and extrapolate with the basic understanding to build seemingly complex stuff. Coming to what you are trying to achieve:
We know, an array can be declared for any data-type (primitive or derived, one might call them POD and ADT).
We know, struct can comprise of any number of elements of any data-types.
Now, we can see that it is just as natural to say MyStruct[] as it is to int[].
It is better to prefer std::array if using modern compiler.

Related

How to allocate memory fo array of objects

I am trying to create an array of objects in C++. As C++ Supports native objects like int, float, and creating their array is not a problem.
But when I create a class and create an array of objects of that class, it's not working.
Here is my code:
#include <iostream>
#include <string.h>
using namespace std;
class Employee
{
string name;
int age;
int salary;
public:
Employee(int agex, string namex, int salaryx)
{
name = namex;
age = agex;
salary = salaryx;
}
int getSalary()
{
return salary;
}
int getAge()
{
return age;
}
string getName()
{
return name;
}
};
int main(void)
{
Employee **mycompany = {};
//Create a new Object
mycompany[0] = new Employee(10, "Mayukh", 1000);
string name = mycompany[0]->getName();
cout << name << "\n";
return 0;
}
There is no compilation error, but when I'm running the Program, it is crashing. I don't know exactly what is happening here.
Please Help.
Here are some more details:
OS: 64bit Windows 8.1 on Intel x64 (i3) Architecture of Compiler: MinGW64 G++ Compiler
The advice here, as always, is to use some STL container, like an std::vector.
That said you're probably going to need a default Employee constructor (unless you always initialize all the elements of the container with the constructor you already have, which is unlikely what you'll do, if you are to manually allocate memory, but more likely if you use a std::vector).
//...
Employee() = default; // or Employee(){}
Employee(int agex, string namex, int salaryx)
{
name = namex;
age = agex;
salary = salaryx;
}
//...
If you really, absolutely, must do it by manual memory allocation, it would look roughly like this:
// Employee array with 5 employees, with the first two initialized with your constructor
Employee *mycompany = new Employee[5] {{10, "Mayukh1", 1000}, {20, "Mayukh2", 2000}};
//adding an employee
mycompany[2] = {30, "Mayukh3", 3000};
// it still has space for 2 more
Don't forget to delete the memory afterwards:
delete [] mycompany;
Live demo
this is how you would do that:
#include <iostream>
#include <string.h>
using namespace std;
class Employee
{
string name;
int age;
int salary;
public:
Employee(int agex, string namex, int salaryx)
{
name = namex;
age = agex;
salary = salaryx;
}
int getSalary()
{
return salary;
}
int getAge()
{
return age;
}
string getName()
{
return name;
}
};
int main(void)
{
//Create an Array length of 10
// in c++ its static you have to give the length of the array while declaring
Employee mycompany [10];
//Create a new Object
mycompany[0] = new Employee(10, "Mayukh", 1000);
string name = mycompany[0]->getName();
cout << name << "\n";
return 0;
}

Nested structure function in c++

I'm having trouble with one of my assignments (or maybe I'm overthinking it?)
I need to create
a function to take integer parameters for number of students and tests.
Allocate the memory needed for the array of students and the array of test scores for each student.
Return a pointer to the array of Student structures. No display output is done in this function.
int main()
{
int studentNum;
int testNum;
cout << "How many students are there?\n";
cin >> studentNum;
cout << "How many tests are there?";
cin >> testNum;
system("pause");
return 0;
}
my function
GradeBook *initArrays(int s, int t)
{
GradeBook *ptr;
// Allocate the array of Student structures.
ptr = new GradeBook[s];
// Allocate an array of ints (to hold test scores)
// for each element of the array of Student structures.
for (int count = 0; count < s; count++)
{
ptr[count].tests = new int[t];
}
// Return a pointer to the array of structures.
return ptr;
}
edit: I have edited my function, could i get some opinions on that?
if you are writing this in c++, use classes. if i understand correctly, you should create a structure to save a students id,name,or something and a corresponding grade?
something like:
class Test{
public:
int id;
int grade;
Test(int id, int grade){
this->id = id;
this->grade = grade;
}
};
class Student{
public:
int id;
std::string name;
std::vector<Test> tests;
Student(int id, std::string name)
{
this->id = id;
this->name = name;
}
};
int main(){
vector<Student> students;
int studentnum;
for (int i = 0; i < studentnum; i++){
students.push_back(Student(i, "name"));
//insert all tests of the student by calling students[i].tests.push_back(Test(id, grade))
}
}
this way you don't have to allocate memory, which you can easily overlook freeing.
edit:
this is very basic and not a sophisticated solution, as the properties of the classes are all public.
edit 2:
typedef struct Test{
int id;
int grade;
}Test;
typedef struct Student{
int id;
std::string name;
Test * tests;
}Student;
int main(){
Student * students;
int studentnum;
students = (Student*)malloc(sizeof(Student)*studentnum);
for (int i = 0; i < studentnum; i++){
students[i]->id = id;
students[i]->name = "name";
student[i]->tests = (Test*)malloc(sizeof(Test)*numberofgradesofthatstudent);
for (int j = 0; j < numberofgradesofthatstudent; j++)
{
students[i]->tests[j]->id = testid;
students[i]->tests[j]->grade = grade;
}
}
}
this is schematic! new and malloc reserve memory on the heap, do not forget to free everything when you are done with it.
As said a little above, be careful using brackets {} to delimit your blocks.
Secondly,the syntax:
array[studIndex].Tests
supposes that the value array[studIndex] (here an integer) has a member value named Tests. But in this case it doesn't.
Think about your problem: you need to store two values "connected" to one another in a static array. The way I see it, you should try on with two dimensional arrays:
int 2dArray[nbStudents][nbTests];
If you don't want to bother with 2dimensional arrays, you can also try
int 2dArray[nbStudents * nbTests];
But for conveniance, it is often better to use 2d arrays.
Also, think about declaring your array before the for loops in your function.
Then concatenate two for loops as you did and I'll let you think about the rest...

how to use a variable in the name of another variable in C++

I'm using a struct like below:
struct Employee{
string id;
string name;
string f_name;
string password;
};
I wanna have a for loop and every time that I increment i I want to make an object from my struct like this:
for(int i= 0; i<5; i++){
struct Employee Emp(i) = {"12345", "Naser", "Sadeghi", "12345"};
}
All I want is to have objects which are name differently by adding i's value to the end of their names every time like Emp1.
C++ doesn't have exact functionality that you ask for. For keepings things together you need to use arrays or other containers. Then, for access you have to use indexers.
Below is working solution for you question (also here):
#include <vector>
#include <iostream>
#include <string>
struct Employee {
std::string id;
std::string name;
std::string f_name;
std::string password;
};
int main() {
std::vector<Employee> employees; // vector for keeping elements together
for (int i = 0; i<5; i++) {
// push_back adds new element in the end
employees.push_back(Employee{ "12345", "Naser", "Sadeghi", "12345" });
}
std::cout << employees.size() << std::endl; // 5 returns how many elements do you have.
std::cout << employees[0].name; // you access name field of first element (counting starts from 0)
return 0;
}

Getting average from passed subjects in structure

I enter info about the student first name lastname index number and degree for each subject.If the degree is over 5 the subject is passed and i get average from passed subjects.If i print the function like printf("%f",P.averagefunc()) the number is ok but i when i try to get the average to variable like float average=P.averagefunc(); inside struct student or float average=averagefunc(); inside struct subject and i print the result i get some weird number like -888266.00000.Any help how i can get the float function to float variable?
Please dont downvote the question i am new to this and i tried to explain my problem as best as i could.
struct subject{
int programming;
int electronics;
int calculus1;
int english;
int usersoftware;
float averagefunc()
{
int sum=0;
int passed=0;
if(programming>5)
{
sum+=programming;
passed++;
}
if(electronics>5)
{
sum+=electronics;
passed++;
}
if(calculus1>5)
{
sum+=calculus1;
passed++;
}
if(english>5)
{
sum+=english;
passed++;
}
if(usersoftware>5)
{
sum+=usersoftware;
passed++;
}
return (float)suma/(float)polozeni;
}
};
struct student{
char firstname[10];
char lastname[15];
int indexnumber;
struct subject P;
};

create an array of class objects in c++

Hi guys I want to make an array of class objects....so that I can keep on creating as many objects during runtime as and when required
I wrote the following code, but its giving me error:
class contact{
public:
string name;//ALL CLASS VARIABLES ARE PUBLIC
int phonenumber;
string address;
contact(){//Constructor
name= NULL;
phonenumber= NULL;
address= NULL;
}
void input_contact_name(string s){//function to take contact name
name=s;
}
void input_contact_number(int x){//function to take contact number
phonenumber=x;
}
void input_contact_address(string add){//function to take contact address
address=add;
}
}
int main(){
contact *d;
d= new contact[200];
string name,add;
int choice;//Variable for switch statement
int phno;
static int i=0;//i is declared as a static int variable
bool flag=false;
cout<<"\tWelcome to the phone Directory\n";//Welcome Message
cout<<"Select :\n1.Add New Contact\n2.Update Existing Contact\n3.Delete an Existing Entry\n4.Display All Contacts\n5.Search for a contact\n6.Exit PhoneBook\n\n\n";//Display all options
cin>>choice;//Input Choice from user
while(!flag){//While Loop Starts
switch(choice){//Switch Loop Starts
case 1:
cout<<"\nEnter The Name\n";
cin>>name;
d[i]->name=name;
cout<<"\nEnter the Phone Number\n";
cin>>phno;
d[i]->input_contact_number(phno);
cout<<"\nEnter the address\n";
cin>>add;
d[i]->input_contact_address(add);
i++;
flag=true;
}
}
return 0;
}
Please can some one out figure out the reason??
Thanks in advance
Many problems:
Missing semicolon on the closing brace of the class, as maverik noted
Use of string without using namespace std; or using std::string; (or #include <string> for that matter)
Ditto #2 for cin and cout (and <iostream>)
d[i]-> is wrong; d[i] is a contact&, not a contact*, so use . instead of ->
name= NULL; and address= NULL; are nonsensical -- string is not a pointer type, and already default-constructs to empty
phonenumber= NULL; is technically valid, but still 'wrong'
Also, good lord, use some whitespace in your code.
EDIT (in response to comment): Your constructor should look like:
contact() : phonenumber() { }
You forget the ;
class contact {
...
}; // <- ; is neccessary