How to use pointers into structure - c++

I have a structure sportist
struct sportist{
string name;
string surname;
int goals;
string tim;
}
Here is the function that should read the values.
void read(sportist x[],int n)
{
int i;
for(i=0;i<n;i++)
{
cout<<"************************************************"<<endl;
cout<<"Name:";
cin>>x[i].name;
cout<<endl<<"Surname:";
cin>>x[i].surname;
cout<<endl<<"Goals :";
cin>>x[i].goals;
cout<<endl<<"Name of the team:";
cin>>x[i].tim;
}
My question is how can I use pointers, because I need to? My attempt:
void read(sportist* x,int n)
{
int i;
for(i=0;i<n;i++)
{
cout<<"************************************************"<<endl;
cout<<"Name:";
cin>>x->name;
cout<<endl<<"Surname:";
cin>>x->surname;
cout<<endl<<"Goals :";
cin>>x->goals;
cout<<endl<<"Name of the team:";
cin>>x->tim;
}
}
What I want is to sort the sequence of athletes and teams by the number of goals and print them on the screen to sort them in a popup order. But it shows me errors when I debug.

you should pay attention to one point when you are using array x[i] with i increasing ,you are traversing the array ,but with pointer you should move pointer so it would point to next elements of array.You should use x++;.
look:
void read(sportist* x, int n)
{
int i;
for (i = 0; i < n; i++)
{
cout << "************************************************" << endl;
cout << "Name:";
cin >> x->name;
cout << endl << "Surname:";
cin >> x->surname;
cout << endl << "Goals :";
cin >> x->goals;
cout << endl << "Name of the team:";
cin >> x->tim;
x++;
}
}
if you miss x++; each time you will write entered data in first element of array.
Also note in function you are declaring this array of sportist , if you declare sportist* x instead of sportist x[num] ,you have to allocate memory for it too.

Related

Sorting two arrays that are linked into descending order. One is a string array, one is an int array. c++

I'm still relatively new to coding and a recent assignment I had has been stumping me quite a bit.
I have two arrays that are essentially linked to one another. 0 on one side must be 0 on the other, and I need to find the easiest way to sort the one with the numbers into descending order while doing the same to the other side.
int main()
{
/// Declare Variables
int studentNum, j;
int studentGrade[20];
string studentName[20];
/// Prompt the user for the number of loops that will be required
cout << "How many students are in the class? ";
cin >> studentNum;
cout << endl;
/// Enter a for loop
for(int i=0;i<studentNum;i++)
{
/// Prompt the user to enter the names of each student in the array, as well as their respective grade.
cout << "Enter the student's name: ";
cin >> studentName[i];
cout << "Enter the student's grade (0-100): ";
cin >> studentGrade[i];
}
cout << endl << endl;
cout << setw(25) << left << "Student's Name" << setw(25)<< "Test Score" << endl;
///********Sorting block required*********
/// Enter another for loop, this time to show the array to the screen
for (int i=0;i<studentNum;i++)
{
cout << setw(25) << studentName[i] << setw(25) << studentGrade[i] << endl;
}
return 0;
}
I've looked up as many answers to this question as I can, but haven't been able to find something that would work for me. Does anyone know something I could do here? I have to keep these as two separate arrays. If possible as well, I'd like to try not using sort().
You could sort the arrays like this in a double for loop:
for(int j=0 ; j<studentNum ; j++)
for(int i=0 ; i<studentNum-1 ; i++){
if(studentGrade[i] < studentGrade[i+1]){ //swapping condition
string temp = studentName[i];
studentName[i] = studentName[i+1];
studentName[i+1] = temp;
int x = studentGrade[i];
studentGrade[i] = studentGrade[i+1];
studentGrade[i+1] = x;
}
}
If the grade of a student in the array is lower than the grade of the student next to him in the array then you could swap them and also swap their names respectively
it doesn't matter what sorting algorithm you choose, you just need to go through one of the arrays and whenever you change a cell's index you do it to the same cell index in the other array
for example:
for (int i = 0; i < size; i++){
if(arr[i]<arr[i+1]){
temp=arr[i];
temp2=arr2[i];
arr[i]=arr[i+1];
arr2[i]=arr2[i+1];
arr[i+1]=temp;
arr2[i+1]=temp2;
}
}
Use the C++ STL conventions, vector, pair and sort
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
vector<pair<string, int> > students;
cin >> n;
// Input name and grade of all students
while (n--) {
string name;
int grade;
cin >> name >> grade;
students.push_back(make_pair(name, grade));
}
// Sort students based on their grades descending
sort(students.begin(), students.end(),
[](const auto & a, const auto & b) -> bool {
return a.second > b.second;
});
// Output students' name and grade
for (auto & s : students) {
cout << setw(25) << s.first << setw(25) << s.second << endl;
}
return 0;
}

Passing dynamic arrays to recieve inputs in separate functions

I would like to pass dynamic arrays to functions and receive user input. Currently I'm using the following code:
#include <iostream>
using namespace std;
struct make
{
int part;
int graph;
int like;
};
int z;
int *p = new int [z];
void inpart( make x[],int *fig)
{
cout << "Input part\n";
cin >> x[*fig].part;
}
void ingraph(make x[],int *tig)
{
cout << "Input graph\n";
cin >> x[*tig].graph;
}
void inlike(make x[],int *gig)
{
cout << "Input like\n";
cin >> x[*gig].like;
}
int main()
{
cout << "Input array count\n";
cin >> z;
make p[z];
for (int i=0; i < z; i++)
{
inpart(p,&z);
ingraph(p,&z);
inlike(p,&z);
}
for (int i=0; i < z; i++)
{
cout << "the result is\n";
cout << p[z].part << ", ";
cout << p[z].graph << ", ";
cout << p[z].like << "\n";
}
}
My input 1,1,1 for all the structure objects should output 1,1,1. However, the answer I receive is 1,0,2. Why?
Firstly, you shouldn't trying to initialize a static buildin array in run-time:
Your implementation is wrong here:
cout<< "Input array count\n";
cin>>z;//initialized in run-time
make p[z]; // wrong, need to be allocated with new
make* example = new make[z]; // Ok!
Secondly, you're trying to read and write out of bounds of the created array. It's Undefined behaviour. When you're creating an array with size N, chunk of the memory will be allocated to which you can have access by index. In your case from 0 to z or [0,z), excluding z. To sum up, your cycle should look like this:
for (int i = 0; i < z; i++) {
inpart(p,&i);
ingraph(p,&i);
inlike(p,&i);
}
Actually u've made a lot of mistakes in your code, but I feel like you will understand this later when continue learning.

How to Create & Add new object in existing array using Dynamic Memory allocation

I am trying to do some stuff with C++ and i am new in it :)
I have tried 1 program of class that gets the student details and print the output of it.
#include <iostream>
using namespace std;
#define MAX 10
class student
{
private:
char name[30];
int rollNo;
int total;
float perc;
public:
//member function to get student's details
void getDetails(void);
//member function to print student's details
void putDetails(void);
};
//member function definition, outside of the class
void student::getDetails(void){
cout << "Enter name: " ;
cin >> name;
cout << "Enter roll number: ";
cin >> rollNo;
cout << "Enter total marks outof 500: ";
cin >> total;
perc=(float)total/500*100;
}
//member function definition, outside of the class
void student::putDetails(void) {
cout << "Student details:\n";
cout << "Name:"<< name << ",Roll Number:" << rollNo << ",Total:" << total << ",Percentage:" << perc;
}
int main()
{
student std[MAX]; //array of objects creation
int n,loop;
cout << "Enter total number of students: ";
cin >> n;
for(loop=0;loop< n; loop++){
cout << "Enter details of student " << loop+1 << ":\n";
std[loop].getDetails();
}
cout << endl;
for(loop=0;loop< n; loop++) {
cout << "Details of student " << (loop+1) << ":\n";
std[loop].putDetails();
}
return 0;
}
Its very basic code and works fine and I am able to give inputs and print the output.
Now I want to add new Student object at runtime using Dynamic memory allocation and want to add that object in the existing array of object (So that I can get the highest, lowest marks of any student)
I know I need to use new operator for this.
But I am not sure what could be the best way to write this solution.
Any help will be highly appreciated.
Thanks!
IMO, The best way to do this using dynamic memory is by using std::unique_ptr or std::shared_ptr (it actually depends on the requirement).
Here is one example of usage of unique_ptr:
using StudentPtr = std::unique_ptr<student>;
int main() {
std::vector<StudentPtr> studentDetails;
int n;
cout << "Enter the number of students: ";
cin >> n;
studentDetails.resize(n);
for (auto &s: studentDetails) {
s = StudentPtr(new student);
s->getDetails();
}
return 0;
}
For getting minimum and maximum, you may use min_element and max_element provided by STL respectively.

Loop in function running more than it needs to

In a problem i am working on i have a function that checks if the number of spherical and cylindrical holes in rectangular block are greater than zero. In this problem i have to call the function twice. My problem is that the first time i call the function 'HoleCheck' is is running twice and assuming that zero is entered in for the cylindrical holes and makes me re-enter the value for spherical holes. How can i make it to only run once for the spherical hole check?
#include <iostream>
#include <string>
using namespace std;
void Check(double arr1[], string arr2[]);
void HoleCheck(int arr3[], string arr4[]);
int main()
{
double DimArray[3];
string MyArray[3] = { "Height", "Length", "Width"};
int totalholes[2];
string holes[2] = { "Spherical", "cylindrical"};
cout << "Enter the height, length and width of rectangle in centimeters: ";
cin >> DimArray[0] >> DimArray[1] >> DimArray[2];
Check(DimArray, MyArray);
cout << "How many spherical bubbles are present? ";
cin >> totalholes[0];
HoleCheck(totalholes, holes);
cout << "How many cylindrical holes are present? ";
cin >> totalholes[1];
HoleCheck(totalholes, holes);
return 0;
}
void Check(double arr1[], string arr2[])
{
int i;
for (i = 0; i < 3; i++)
{
while (arr1[i] <= 0)
{
cout << "Your entered " << arr2[i] << " is less than zero!\n";
cout << "Please re-enter a valid number --> ";
cin >> arr1[i];
}
}
}
void Check(double arr1[], string arr2[])
{
int z;
for (z = 0; z < 2; z++)
{
while (arr3[z] <= 0)
{
cout << "The number of " << arr4[z] << " holes must be greater than 0.\n";
cout << "Please re-enter a valid number --> ";
cin >> arr3[z];
}
}
}
Assuming that your second Check function is actually HoleCheck and that was a typo:
Your HoleCheck Function checks both elements of its arr3, but you are calling it before you enter any values into totalHoles[1].
Either just remove the first call to HoleCheck or change it so you can tell it which entry in the array to check.

c++ memory leak on my data structure

So I've graduated from learning C and now learning C++. From what I understand C and C++ are similar in variety of ways so I'm trying to re-write my past C project files into C++. However I keep getting a memory leak when I try to print out my information. Can someone tell me why I am getting a memory leak in my code.
struct.h
typedef struct student_info {
char last[10];
char first[10];
int student_id;
int count_student;
} student;
typedef struct course_info {
char name[10];
int course_id;
int count_course;
student *students;
} course;
typedef struct gradebook_info {
course *courses;
} gradebook;
function.c
void new_course(gradebook *info) {
int i, loop=0;
cout << "Enter Number of Courses " ;
cin >> loop;
for(i=0; i<loop; i++) {
cout << "Enter Course ID ";
cin >> info->courses[info->courses->count_course].course_id;
cout << "Enter Course Name ";
cin >> info->courses[info->courses->count_course].name;
info->courses->count_course++;
}
}
void new_student(gradebook *info) {
int i, loop=0;
cout << "Enter Number of Students " ;
cin >> loop;
for(i=0; i<loop; i++) {
cout << "Enter Student ID ";
cin >> info->courses->students[info->courses->students->count_student].student_id;
cout << "Enter Last Name ";
cin >> info->courses->students[info->courses->students->count_student].last;
cout << "Enter First Name ";
cin >> info->courses->students[info->courses->students->count_student].first;
info->courses->students->count_student++;
}
}
void printCourse(gradebook *info) {
int i;
cout << "Course ID\tCourse Name\t" << endl;
for(i=0; i<info->courses->count_course; i++) {
cout << info->courses[i].course_id << "\t\t";
cout << info->courses[i].name << endl;
}
}
void printStudent(gradebook *info) {
int i;
cout << "Student ID\tLast Name\tFirst Name\t" << endl;
for(i=0; i<info->courses->students->count_student; i++) {
cout << info->courses->students[i].student_id << "\t\t";
cout << info->courses->students[i].last << "\t\t";
cout << info->courses->students[i].first << endl;
}
}
When I run new_course() function it works.
I run my printCourse() function it works.
I run new_student() function it works.
When I run printStudent() function it works.
Then I try to run printCourse() function again and when i=2, I get some information from my struct student.
I can't figure it out. Any help is appreciated.
main.c
gradebook *info = new gradebook; //allocate memory
do {
main_menu();
int option=0;
switch(option) {
case 1: new_course(info);
break;
case 2: new_student(info);
break;
case 3: printCourse(info);
break;
case 4: printStudent(info);
break;
}
}while(option < 13);
delete(info);
You need to allocate the pointers students and course using new.
After getting loop:
students = new student_info* [loop]
and
courses= new course_info* [loop]
You have not only to allocate memory for the gradebook, but also for the courses and the students. For example:
gradebook *info = new gradebook;
info->courses = new course_info[10];
for(int i = 0; i < 10; i++)
info->courses[i]->students = new student_info[10];
Beware, this example limits the number of courses and students per course to 10.
P.S.: Your code might work for one or two iterations if you don't allocate memory for the courses and the students. But in this case you screw up your memory.