C++ having input to class - c++

I made 2 function : getdata, print for input/print variable in person class
#include <iostream>
#include <string>
using namespace std;
class person {
public:
char name[19];
int born_year, married_year;
};
void getdata(char* name, int born_year,int married_year) {
cout << "Enter Name!\n > ";
cin.getline(name, 19);
cout << "What's the Born Year?\n > ";
cin >> born_year;
cout << "What's the Married Year?\n > ";
cin >> married_year;
}
void print(char* name, int born_year, int married_year) {
cout << "Your Name : " << *name;
cout << "\n Your Born Year : " << born_year;
cout << "\n Your Married Year : " << married_year;
}
int main(void) {
person p;
int born_year, married_year;
getdata(p.name, p.born_year, married_year);
print(p.name, p.born_year, p.married_year);
return 0;
}
I'm trying to have input in a function outside the class
(class only have variables about person)
and print with with other function.
How could I make this work?

Your problem is in the variable types to your getdata function. The integer parameters need to be pass-by-reference (either pointers or references, the latter being preferred). Right now you pass in a copy of the born_year and married_year values. When you get the input you save that into local variables; the passed parameters are never updated.
You want something like this:
void getdata(char* name, int &born_year,int &married_year)
With that tiny change (adding the two & characters) your code should work as you expect.

#include <iostream>
#include <string>
using namespace std;
class person {
public:
char name[19];
int born_year, married_year;
};
void getdata(char* name, int &born_year, int &married_year) {
cout << "Enter Name!\n > ";
cin.getline(name, 19);
cout << "What's the Born Year?\n > ";
cin >> born_year;
cout << "What's the Married Year?\n > ";
cin >> married_year;
}
void print(char* name, int born_year, int married_year) {
cout << "Your Name : " << name;
cout << "\n Your Born Year : " << born_year;
cout << "\n Your Married Year : " << married_year;
}
int main(void) {
person p;
getdata(p.name, p.born_year, p.married_year);
print(p.name, p.born_year, p.married_year);
return 0;
}

If you want passed variables to be changed inside a function you need to pass them by reference. To do that you need to make some changes in your function definition:
void getdata(char* &name, int &born_year, int &married_year) {
//things you function does
}

Everything looks fine. Just you need to call 'function by reference' to directly change values of class variable.
https://www.tutorialspoint.com/cplusplus/cpp_function_call_by_reference.htm
void getdata(char* name, int born_year,int married_year)
you can remove variables declared in main function and use p. before every parameter.
getdata(p.name, p.born_year, p.married_year);

As others have mentioned your problem was that you were passing copies of the values in, not the variables themselves. Also you forgot to put the "p" on "married_year" in your main loop.
However, rather than passing in the separate values by reference, a much nicer idea is passing in a reference to the whole person:
int main(void) {
person p;
getdata(p);
print(p);
return 0;
}
Getdata and print would look like this:
void getdata(person &p) {
cout << "Enter Name!\n > ";
cin.getline(p.name, 19);
cout << "What's the Born Year?\n > ";
cin >> p.born_year;
cout << "What's the Married Year?\n > ";
cin >> p.married_year;
}
void print(const person &p) {
cout << "Your Name : " << *(p.name);
cout << "\n Your Born Year : " << p.born_year;
cout << "\n Your Married Year : " << p.married_year;
}
It's a cleaner way to do it, and since you're not creating or passing as many variables around, there are less ways to make a mistake here. If you made the fields private however, you'd need to make the two functions "friend" of the class to access its members.

Related

i made c++ code where its need to pass structure pointer in a function

i got confused about the structure when i need to to pass the value in a function
#include <iostream>
using namespace std;
struct student
{
int studentID;
char studentName[30];
char nickname[10];
};
void read_student(struct student *);
void display_student(struct student *);
int main()
{
student *s;
//struct student *ps;
read_student(s);
display_student(s);
}
void read_student(struct student *ps)
{
int i;
for (i = 0; i <= 2; i++)
{
cout << "Enter the studentID : ";
cin >> ps->studentID;
cout << "Enter the full name :";
cin.ignore();
cin >> ps->studentName;
cout << "Enter the nickname : ";
cin.ignore();
cin >> ps->nickname;
cout << endl;
}
}
void display_student(struct student *ps)
{
int i;
cout << "student details :" << endl;
for (i = 0; i <= 2; i++)
{
cout << "student name : " << *ps ->studentName << " (" << &ps ->studentID << ")" << endl;
ps++;
}
}
its only problem at the variable at line 19 and when i try to edit it will became more problem
student *s;
//struct student *ps;
//struct student *ps;
read_student(s);
display_student(s);
also can someone explain how to transfer pointer value of structure to the function and return it back to the main function
You are suffering from some leftovers from your C-Language time. And, you have still not understood, how pointer work.
A pointer (as its name says) points to something. In your main, you define a student pointer. But it is not initialized. It points to somewhere. If you read data from somewhere, then it is undefined behavior. For writing, it is the same, plus that the system will most likely crash.
So, define a student. And if you want to give it to a sub-function, take its address with th &-operator (this address will point to the student) and then it will work.
You need also to learn abaout dereferencing. Your output statement is wrong.
Last but not least, if you want to store 3 students, then you need an array or some other storage where to put them . . .
In your read function you always overwrite the previously read student and in your display function you show undetermined data.
Please have a look at your minimal corrected code:
#include <iostream>
using namespace std;
struct student
{
int studentID;
char studentName[30];
char nickname[10];
};
void read_student( student*);
void display_student( student*);
int main()
{
student s;
//struct student *ps;
read_student(&s);
display_student(&s);
}
void read_student( student* ps)
{
cout << "Enter the studentID : ";
cin >> ps->studentID;
cout << "Enter the full name :";
cin.ignore();
cin >> ps->studentName;
cout << "Enter the nickname : ";
cin.ignore();
cin >> ps->nickname;
cout << endl;
}
void display_student( student* ps)
{
cout << "student details :" << endl;
cout << "student name : " << ps->studentName << " (" << ps->studentID << ")" << endl;
ps++;
}
And, the commenters are right. You must read a book.

Is there any way to enter 10 students detail in parameterized constructor and print it using member function with array of object in c++

I tried this code but when I am calling the member function inside the loop it is giving the garbage value of the details and when I am calling the member function outside the loop it is giving me error.
#include<iostream>
#include<string.h>
using namespace std;
class student
{
char name[10];
int id,rollno;
public:
student(char name[10],int id,int rollno)
{
strcpy(this->name,name);
this->id=id;
this->rollno=rollno;
cout<<"the name of the student is:"<<name<<endl;
cout<<"the id of the student is:"<<id<<endl;
cout<<"the roll no of the student is:"<<rollno<<endl;
}
};
int main()
{
int id1,rollno1;
char name1[10];
for(int i=1;i<=2;i++)
{
cout<<" enter the detail of the student "<<i<<" "<<endl;
cout<<"enter the name of the student:";
cin>>name1;
cout<<"enter the id of the student:";
cin>>id1;
cout<<"enter the roll no of the student:";
cin>>rollno1;
student d[]={student(name1,id1,rollno1)};
d[i].print();
}
return 0;
}
Here's your code review.
#include <iostream>
#include <string.h>
using namespace std; // it is strongly suggested that you don't use the whole header unless your intent is speeding up coding
class Student // capitalize classes
{
char _name[10];// it is ok, however, if you use the <string> header, why would you go back to char type?
int _id, _rollno;
public:
Student(char name[10] /* this is just the array's first item passed! */, int id, int rollno)
{
// Don't use this->, use an underscore for one of the names.
// I use underscores for the encapsulated data
strncpy_s(_name, name, 9);// a safer version
_id = id;
_rollno = rollno;
cout << "\nCtor says: ";
cout << "the name of the student is: " << _name << endl;
cout << "the id of the student is: " << _id << endl;
cout << "the roll no of the student is: " << _rollno << endl;
cout << '\n';
}
const char* getName() { return _name; }
const int getId() { return _id; }
const int getRollNo() { return _rollno; }
// unless you overload operator<< , you have to make getters for your info, or make it public
};
int main()
{
int id, rollno;// why 1? they won't intersect with the function
char name[10];
Student *s[2];//you must make that on the heap; otherwise you need a default constructor
for (int i{ 0 }; i < 2; i++)// start with 0 and make it just <
{
cout << "enter the details of the student " << i << endl;// Why so many spaces?
cout << "enter the name of the student: "; // add space after the colon
cin >> name;// remember, you're limited to 9 chars + \n !!!
cout << "enter the id of the student: ";
cin >> id;
cout << "enter the roll no of the student: ";
cin >> rollno;
//student d[] = { student(name,id,rollno) }; // you can't do this. It's not flexible.
// You either assign enough space for the intended number of students in the stack, statically, or
// you lett it find more space in the heap = dynamically
//this goes to the heap
s[i]= new Student( name,id,rollno );// parentheses are well
//s[i] = new Student{ name,id,rollno };// initializer list may also do
//d[i].print();// what's to print here? It's not POD, cout needs instructions
cout << "Stored data -> Id: " <<
s[i]->getId() << ", Name: " // -> dereferences the pointer, and s is a pointer now
<< s[i]->getName() << ", Roll no: "
// or you can dereference it
<< (*s[i]).getRollNo()
<< endl << endl; // make some extra space here
}
return 0;
}

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.

How to use <vector> with constructor

How could I use <vector> for an array of objects, which need to be given value through constructors? e.g class with name,age would need to get in an array with information given through constructor Student(string n, int a ) { name = n , age = a } .
All the data will be given through keyboard..
Here is an example code of a program capable of getting and storing the name and the age of a list of students using vectors. After that, it prints the information stored. I am using MSVC as the compiler, so if you are not on windows, you can remove system("pause"):
#include <vector>
#include <string>
#include <iostream>
using namespace std;
class Student {
public:
Student(string n, int a) : name(n), age(a) {}
string GetName(void) { return name; }
int GetAge(void) { return age; }
private:
string name;
int age;
};
int main(void) {
vector<Student> students;
unsigned int n;
cout << "How many students are there?" << endl;
cin >> n;
for (unsigned int i = 0; i < n; ++i) {
string name;
int age;
cout << endl << "Please give me the information of the student " << i + 1 << endl;
cout << "What is the name of the student?" << endl;
cin >> name;
cout << "What is the age of the student?" << endl;
cin >> age;
students.push_back(Student(name, age));
}
cout << endl << "Printing information of the students" << endl << endl;
for (unsigned int i = 0; i < n; ++i) {
Student& student = students[i];
cout << "Student " << i + 1 << " is " << student.GetName() << " and is " << student.GetAge() << " years old." << endl;
}
system("pause");
return 0;
}
One can use an initializer-list to directly construct a vector of students:
std::vector<Student> students{
{ "John", 22 },
{ "Melissa", 19 }
};
To add a student later one could use member function emplace_back() which just forwards its arguments to the Student constructor:
students.emplace_back( "Andy", 23 );
Pre C++11 one would have to use member function push_back() instead:
students.push_back( Student( "Andy", 23 ) );
More usage examples can be found on the linked reference pages.

Sorting names between a Student class

edit. I want to thank the two people who helped me in my code. I fixed my coding as of 7:22 PM PST 9/25/2014. Still having trouble with the sorting though.
So I'm trying to teach myself how to use C++ in order to get ahead of my programming class in school. I've already taken Java so I'm relatively familiar with the structure of the coding but not exactly sure what to be typing. This practice problem is:
1)Ask the user how many people he wants to enter into the list.
2)Read 3 strings, then turn that info into a student class and put the student inside a vector.
3)Sort the list by name. (Extra credit would be to sort the list by Student ID)
4)Print the info of each student in the list.
5)Ask user while answer is 'Y', search the list for a name and print the info correlating to the name
While in Java, this seems pretty easy, I'm having an extremely hard time understanding what is going on in C++.
I currently only have 1, 2, 4 and 5 done. This is what I have so far.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
#include <fstream>
#include <iomanip>
using namespace std;
class Student
{
string myName, myStudentID, myClassID;
public:
Student(string name, string studentID, string classID)
{
myName = name;
myStudentID = studentID;
myClassID = classID;
}
string getName() { return myName; }
string getStudentID() { return myStudentID; }
void printInfo() { cout << myName << setw(15) << myStudentID << setw(10) << myClassID << endl; }
};
int main()
{
int num;
std::vector<Student> studentList;
cout << "How many students do you wish to add to the student list ? " << endl;
cin >> num;
cin.ignore();
for (int a = 0; a < num; a++)
{
string inputName, inputStudentID, inputClassID;
//get name
cout << "Please enter the Student name : ";
getline(cin, inputName);
//get student ID
cout << "Please enter the Student ID number : ";
getline(cin, inputStudentID);
//get class ID
cout << "Please enter the Student class ID : ";
getline(cin, inputClassID);
Student thisStudent(inputName, inputStudentID, inputClassID);
studentList.push_back(thisStudent);
cout << endl;
}
//sort(studentList.begin(), studentList.end());
/*
I never figured out how to sort the list by name.
I do not know how to compare the name of studentList[0] and studentList[1]
to put them in alphabetical order.
*/
cout << endl;; // FORMATTING
cout << "The student list has a size of " << studentList.size() << endl;
cout << endl;; // FORMATTING
cout << "Student Name" << setw(15) << "Student ID" << setw(10) << "Class ID" << endl;
for (int a = 0; a < studentList.size(); a++)
{
studentList[a].printInfo();
}
cout << endl;; // FORMATTING
string searchedName;
char answer;
do
{
cout << endl;; // FORMATTING
cout << "Please type the name of the person you want to search for: ";
getline(cin, searchedName);
for (int a = 0; a < studentList.size(); a++)
{
if (searchedName.compare(studentList[a].getName()) == 0)
{
studentList[a].printInfo();
break;
}
else
if (a == (studentList.size() - 1)) //If went to end of the list, tell them name not found.
cout << "There is no " << searchedName << " in the list. \n";
}
cout << "Would you like to search for another person? \n";
cout << "Y for Yes, N for No. \n";
cin >> answer;
cin.ignore();
} while (answer == 'Y' || answer == 'y');
return 0;
}
You could create a static compare function in class Student to use with std::sort
class Student
{
string myName, myStudentID, myClassID;
// ...
static bool compare_name(const Student & lStudent, const Student & rStudent)
{return (lStudent.myName < rStudent.myName);}
};
// ...
std::sort(studentList.begin(), studentList.end(), Student::compare_name);
or if your compiler supports lambda functions:
std::sort(studentList.begin(), studentList.end(),
[studentList](const Student & lStudent, const Student & rStudent)
{return (lStudent.myName < rStudent.myName);});