Run time error in pointers to structure - c++

i was exploring all the possibilities in structures in C++, and when i came to the topic pointers to structure i got stuck with some run time error.
Here is my code:
#include<iostream>
#include<string>
using namespace std;
// globally defined structure can be used in any method
struct stud
{
int roll;
string sname;
// nested structure for date of birth
struct dob
{
int date;
int month;
int year;
} dob1;
int marks1;
int marks2;
int marks3;
} stud1 = {1,"pranshu1",{11,4,1993},65,87,80};
// function to calculate average of a student
float calaverage(stud s1)
{
float savg=s1.marks1+s1.marks2+s1.marks3;
savg=savg/3;
return savg;
}
// function to calculate the average of whole class
// function parameter are the starting address of the array of the structure stud
// and the total no of elements in the array
float avgclass(stud *ptr, int no_of_stud)
{
float classtotal=0;
for(int i=0;i<no_of_stud; i++)
{
classtotal=classtotal+calaverage(*(ptr+i));
}
return classtotal;
}
int main()
{
// array of structure
struct stud class1[3]=
{
stud1,
{2,"pranshu2",{11,4,1993},80,95},
{3,"pranshu3",{11,4,1993},64,84,93}
};
// initializing the value by accessing the member
class1[0].marks3=93;
struct stud* stud5;
stud5->roll=10;
stud5->sname="pranshu";
stud5->dob1.date=11;
stud5->dob1.month=4;
stud5->dob1.year=93;
stud5->marks1=97;
stud5->marks2=45;
stud5->marks3=98;
cout<<stud5->roll<<endl;
// average marks of student 1
cout<<"Average marks of "<<stud1.sname<<" with roll no "<<stud1.roll<<" is "<<calaverage(stud1)<<endl;
// class average
cout<<"Class average is "<<avgclass(class1,3)<<endl;
}
The error was with stud5, but i didnt get any clue about it..

struct stud* stud5; is just a pointer ... you should allocate also memory:
stud5 = new stud;
to have an object.

Related

Discerning between struct indexing and size initialization

I'm trying to write a function that takes an array of structs and will sort the elements of the array alphabetically by accessing the first data member. I'm struggling to get the code to distinguish between when I'm referring to a data member versus initializing the size of an array. For example, the following code
void selectionSort(struct A[], int size)
{
int mindex;
for (int ct1 = 0; ct1 < size - 1; ct1++)
{
mindex = ct1;
for (int ct2 = ct1 + 1; ct2 < size; ct2++)
if (A[ct2].state < A[mindex].state)
mindex = ct2;
swap(A[mindex], A[ct1]);
}
}
complains that ct2 is not constant, when I'm clearly using it as an index. How would I get this to run correctly? That is, how can I get it to compare data members in their respective indices rather than think I'm initializing the size of a struct variable?
Edit The error message I am receiving is expression must have a constant value for the variable ct2.
I think you might have a problem with how you're creating your function. Usually, when you declare an array of structs it looks like this.
struct Student {
int uid;
string name;
};
Student studentArry[3];
You would use 'Student' or the name of your struct to initialize your array. For example, int arr[10] is an integer array of size 10 while Student arr[10] is a student array of size 10.
One other side note, if you're trying to create a function that is passed a struct you have to initialize the struct before you define the function. This code will work because the struct was declared before the function was.
#include <iostream>
using namespace std;
struct Student {
int uid;
string name;
};
void print(Student array[], int size){
for(int i = 0; i < size; i++){
cout << array[i].uid << endl;
cout <<array[i].name<< endl;
}
};
int main(){
Student StudentRecords[2] = {
{19, "John Smith"},
{21, "Jim Pop"}
};
print(StudentRecords, 2);
return 0;
}
The code below will not because the print function doesn't know what type student is.
#include <iostream>
using namespace std;
void print(Student array[], int size){
for(int i = 0; i < size; i++){
cout << array[i].uid << endl;
cout <<array[i].name<< endl;
}
};
int main(){
struct Student {
int uid;
string name;
};
Student StudentRecords[2] = {
{19, "John Smith"},
{21, "Jim Pop"}
};
print(StudentRecords, 2);
return 0;
}
So, all in all, I think you need to change how you're creating the parameter for the function and possible where you're declaring your struct.

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...

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;
};

String in struct in struct in 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.

C++ "No matching constructor for initializing Employee"

I am new to C++ and practicing using vector as an object. However, I got an error "No matching constructor for initializing Employee" when I tried running the following program.
Please tell me how I could modify my program!
Also, when I write
staff[0] = Employee{"Harry Potter" 55000};
does this mean that I am storing string and double data in one of 10 open boxes in vector object of type Employee?
I apologize for such a basic question.
Thank you so much in advance!!
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class Employee
{
public:
Employee(string, double);
double get_salaries();
string get_name();
void set_salaries(double);
private:
string name;
double salaries;
};
Employee::Employee(string n, double s)
{
name = n;
salaries = s;
}
double Employee::get_salaries()
{
return salaries;
}
string Employee::get_name()
{
return name;
}
void Employee::set_salaries(double s)
{
salaries = s;
}
int main()
{
// using vector as an object
int i;
vector<Employee> staff(10);
staff[0] = Employee{"Harry Potter", 55000};
if (staff[i].get_salaries() < 100000)
cout << staff[i].get_salaries();
return 0;
}
Your Employee class does not have a default, parameterless, constructor.
When you create the staff vector, it will create 10 Employee objects, thus invoking the default constructor.
To support this,
vector<Employee> staff(10);
you have to provide default constructor in your class.
Your main method
int main()
{
// using vector as an object
int i; // [i] not initialized anywhere.
vector<Employee> staff(10); // Incorrect way of declaring a vector
staff[0] = Employee{"Harry Potter", 55000}; // Incorrect way of creating a instance of class
if (staff[i].get_salaries() < 100000)
cout << staff[i].get_salaries();
return 0;
}
Change your main method like this
int main()
{
vector<Employee> staff;
staff.push_back(Employee("Harry Potter", 55000));
if (staff[0].get_salaries() < 100000)
cout << staff[0].get_salaries();
return 0;
}