classes with two objects - c++

this code is working fine for first instance but for second instance it is not working
input :
poorva
17
26
raju
18
28
for second object i.e raju it is not taking name and roll no and shows some garbage value here is the ideone link https://ideone.com/uxwMAc
#include<bits/stdc++.h>
using namespace std;
class student
{
int roll;
int age;
char name[20];
public:
void getData();
void showData();
};
void student::getData()
{
char n[20];
int a,r;
cout<<"enter name of student \n";
gets(name);
cout<<"enter age of student \n";
cin>>age;
cout<<"enter roll no of student \n";
cin>>roll;
}
void student::showData()
{
cout<<"details are \n\n";
cout<<"name is :";
puts(name);
cout<<"age is "<<age<<endl;
cout<<"roll number is "<<roll<<endl;
}
int main()
{
student poorva ;
student raju ;
//for poorva
poorva.getData();
poorva.showData();
//for raju
raju.getData();
raju.showData();
return 0;
}

puts and gets are C-derived functions from <cstdio>. cin and cout are C++ streams from <iostream>. Don't mix them, they interact badly when they both read from (or write to) the same underlying stream without co-ordinating.
Try using cin.getline instead, and remove puts entirely. Ideally replace your fixed character array with std::string too.
Oh, and don't #include<bits/stdc++.h>. That's an implementation detail. Wherever you got the idea that it's reasonable to use this directly, is a bad place to learn C++ and you should stop using it (and maybe name & shame it here).
Your code should probably begin with
#include <iostream>
instead.

Tey the following
Student raju =new Student () ;
Though that should have worked.
Same with pooja

Related

I am not able to get input after a certain point ( from the user) even though no error pops wile compiling [duplicate]

This question already has an answer here:
How to make cin work after using getline?
(1 answer)
Closed 3 years ago.
This program is a small hospital management program.
It works with C++ and uses binary files and classes.
it is a simple prog that taken the input of patients details and saves in a binary file, and displays the patients details by searching regno.
The code does not run beyond : cin>>A1.PI.age; and starts printing endless loop of something.
PLEASE REPLY ME ON WHERE HAVE I GONE WRONG
here is the code:
#include<iostream.h>
#include<conio.h>
#include<fstream.h>
#include<string.h>
#include<stdlib.h>
class all
{ private:
struct address
{ int house;
char street[30];
char city[30];};
struct patient_info
{ char name[40];
address AD1;
int age;
int maritalstatus;
int regno;
char bldgrp[3];
char sex;
}PI;
int task;
protected:
void firstpinfo();
void showpinfo();
void enterpinfo();
public:
void tasks();
char ch;
int serial;
}A1;
class date :public all
{ private :
int day;
int month;
int year;
public:
void enterdate()
{cout<<"enter day of date";
cin>>day;
cout<<"enter month";
cin>>month;
cout<<"enter year";
cin>>year;
}
void showdate()
{ cout<<day<<"/"<<month<<"/"<<year;}
}D1;
//global variables
int count,attempt;
void main()
{ count=0;
cout<<" HOSPITAL MANAGEMENT SOFTWARE
";
D1.enterdate();
A1.tasks();
getch();
while(count==0)
{ A1.tasks();
cout<<"press 0 to continue and 1 to exit";
cin>> count;
}
getch();
}
void all::tasks()
{ attempt=0;
D1.showdate();
cout<<"select task"<<endl
<<"1.show patient details"<<endl
<<"2.enter details of a patient"<<endl
<<"3.exit prog"<<endl;
cin>>task;
switch(task)
{
case 1: {cout<<"enter regno to display"<<endl;
int search;
cin>>search;
fstream fon;
fon.open("hospital.dat",ios::in|ios::binary);
if(!fon)
{cout<<"error in opening"<<endl;
getch();
exit(0);
}
else
{fon.read((char*)&A1,sizeof(A1));
if(A1.PI.regno==search)
{cout<<"showing details";
A1.showpinfo();}
else
{cout<<"regno not found";}
fon.close();
}
break;}
case 2: {cout<<"adding a new patient";
A1.enterpinfo();
fstream fan;
fan.open("hospital.dat",ios::in|ios::binary);
if(fan)
{fan.write((char*)&A1,sizeof(A1));}
fan.close();
break;}
case 3: { cout<<"exiting...press any key";
getch();
exit(0);
break;
}
default: {cout<<"error... press anykey to try again";
getch();
A1.tasks();
};
}}//END OF TASKS
void all::showpinfo()
{cout<<"patient regno\n"<<A1.PI.regno<<endl;
cout<<"patient name\n"<<A1.PI.name<<endl;
cout<<"address of patient\n"<<A1.PI.AD1.house<<" "<< PI.AD1.street<<" "<<PI.AD1.city<<endl;
cout<<"blood group"<<A1.PI.bldgrp<<endl;
cout<<"sex"<<A1.PI.sex<<endl;
cout<<"data extracted";
}
void all:: enterpinfo()
{
cout<<"enter unique registration number";
cin>>PI.regno;
cout<<"enter patient name"<<endl;
cin.getline(A1.PI.name,50);
cout<<"enter address( house, street, city)"<<endl;
cin>>A1.PI.AD1.house;
cin.getline(A1.PI.AD1.street,30);
cin.getline(A1.PI.AD1.city,30);
cout<<"enter age in years"<<endl;
cin>>A1.PI.age;
cout<<"enter 1 for married and 0 for otherwise"<<endl;
cin>>A1.PI.maritalstatus;
cout<<"enter blood group"<<endl;
cin>>A1.PI.bldgrp;
cout<<"enter M for male and F for female";
cin>>A1.PI.sex;
}
why this happens :
This happens because you have mixed cin and cin.getline.
when you enter a value using cin, cin not only captures the value, it also captures the newline. So when we enter 2, cin actually gets the string ā€œ2\nā€. It then extracts the 2 to variable, leaving the newline stuck in the input stream. Then, when getline() goes to read the input, it sees ā€œ\nā€ is already in the stream, and figures we must have entered an empty string! Definitely not what was intended.
old solution :
A good rule of thumb is that after reading a value with cin, remove the newline from the stream. This can be done using the following :
std::cin.ignore(32767, '\n'); // ignore up to 32767 characters until a \n is removed
A better solution :
use this whenever you use std::getline() to read strings
std::getline(std::cin >> std::ws, input); // ignore any leading whitespace characters
std::ws is a input manipulator which tell std::getline() to ignore any leading whitespace characters
source : learncpp website
goto section (Use std::getline() to input text)
hope this is helpful
#include<iostream>
#include<fstream>
#include<string>
#include<cstdlib>
don't use .h extension
we don't think we need #include<conio.h> anymore
and isn't simpler
getline(cin, A1.PI.name) than cin.getline(A1.PI.name,50)
then resize its max size
A1.PI.name.resize(50);

My c++ program terminated without taking the input.What should i do?

The code below,works fine but it does not take any value for age and terminates.`
#include <iostream>
#include <string>
using namespace std;
class user{
int id,level=1,kills=0,age;
char name[20],server[40];
public:
void get(){
cout<<"Enter your name:";
cin>>name[20];
cout<<"Enter your age:";
cin>>age;
}
};
int main(){
user u;
u.get();
return 0;
}
/*Output
Enter your name:Jack
Enter your age:
C:\Users\user\documents\c++
*/
In the output section ,age is not accepted and the program terminates.
Use string name instead of char name[20] to take multi-character value. char name[20] will terminate after taking a single character.
Also, its valued will not be displayed on giving output.
Modified code for reference.
#include <iostream>
#include <string>
using namespace std;
class user{
int id,level=1,kills=0,age;
string name,server;
public:
void get(){
cout<<"Enter your name:";
cin>>name;
cout<<"Enter your age:";
cin>>age;
}
//test output
void put(){
cout<<name<<endl;
cout<<age<<endl;
}
};
int main(){
user u;
u.get();
//test
u.put();
return 0;
}
Just modify the code to this :
#include <iostream>
#include <string>
using namespace std;
class user{
int id,level=1,kills=0,age;
char name[20],server[40];
public:
void get(){
cout<<"Enter your name:";
cin>>name; // changes done here
cout<<"Enter your age:";
cin>>age;
}
};
int main(){
user u;
u.get();
return 0;
}
Job Done :)
Your problem is here:
cin>>name[20];
Why:
'name[20]' is 21th char of the array you defined before. It counts from 0! As this, it is simply a single char. If you now enter more than a single char, the rest is read by the cin>>age.
Example:
cout<<"Enter your name:";
cin>>name[20];
cout<<"Enter your age:";
cin>>age;
std::cout << "Name " << name << std::endl;
std::cout << "Age " << age << std::endl;
And entering:
Enter your name:1234
Enter your age:Name
Age 234
As you see, the '1' is now in the name and the rest is stored in age.
But attention: You defined your array as `name[20], which means you have 0..19 elements. Accessing name[20] is wrong!
But what you simply want to do was:
cin >> name;
The easiest way to handle strings (a long sequence of characters) or even the strings that have spaces just use the following library in C++.
#include <bits/stdc++.h>
Then just declare a string variable.
String name;
Now you can save a very long string without any error. e.g.
name = jshkad skshdur kslsjue djsdf2341;
and you'll get no error, enjoy ;)

unable to input character array in c++

Code:
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
struct student
{
char name[20];
int id;
float cgpa;
};
int main()
{
student s[100];
int n,i;
cout<<"Enter number of students: ";
cin>>n;
cout<<"Enter records of "<<n<<" students"<<endl;
for(i=0; i<n ; i++)
{
cout<<"Enter name: ";
gets(s[i].name);
cout<<"Enter ID: ";
cin>>s[i].id;
cout<<"Enter CGPA: ";
cin>>s[i].cgpa;
cout<<endl;
}
for(i=0; i<n ; i++)
{
cout<<"\nName: "<<s[i].name;
cout<<"\nID: "<<s[i].id;
cout<<"\nCGPA: "<<s[i].cgpa<<endl;
}
}
output:
Enter number of students: 2
Enter records of 2 students
Enter name: Enter ID:
using sublime text 3
c++
Use <string> for name instead of a character array, then use the cin as usual, instead of gets, to read in the string.
As pointer out by Some Programmer Dude, the enter you pressed is put into the input buffer as a newline '\n' and then later accepted by get() causing it to skip to the next input.
There are two ways you can approach this problem :
Use cin.ignore() at the start of the loop where you take the input.
The better choice will be to get rid of gets(). It has been deprecated since c++14. Secondly, replace the character array with a string.
So the structure would see a modification string name;
And simply do cin>>s[i].name; in the loop.
Thats it.
Also, its preferable to use cstdio instead of stdio.h.

How to find acess a class-method of objects stored in c++ vector?

I am C++ noob, forgive me if this a simple question, I have been trying to solve this problem since past couple of days.
There exists a class called student which stores names, age and marks of a student. Each student's profile (age, name and marks is stored in a class). There are n students in a class hence , a vector<student*> is created, which stores the pointers to all the students profile in a class.
I want to print the values stored in the `vector I would really appreciate any hints!
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <string>
using namespace std;
class student{
private:
string name;
float marks;
int age;
public:
student(): name("Null"), marks(0),age(0){}
student(string n, float m,int a): name(n), marks(m),age(a){}
void set_name();
void set_marks();
void set_age();
void get_name();
void get_marks();
void get_age();
};
void student::set_name(){
cout<<"Enter the name: ";
cin >> name;
}
void student::set_age(){
cout << "Enter the age: ";
cin >> age;
}
void student::set_marks(){
cout<<"Enter the marks ";
cin>> marks;
}
void student::get_name(){
cout<<"Name: "<< name<<endl;
}
void student::get_age(){
cout<<"Age: "<< age<<endl;
}
void student::get_marks(){
cout<<"Marks: "<< marks<<endl;
}
int main() {
int n;
cout<<"Enter the number of students: ";
cin >> n;
vector <student*> library_stnd(n);
for(int i=0;i<n;i++){
student* temp = new student;
temp->set_name();
temp->set_age();
temp->set_marks();
library_stnd.push_back(temp);
}
for (auto ep: library_stnd){
ep->get_age();
}
return(0);
}
vector <student*> library_stnd(n) create a vector of size n. Then in the first for loop library_stnd.push_back(temp) push temp to the end of library_stnd and does not change first n items.
The problem is the first n items in library_stnd is zero initialized[1] and dereferencing it in the second for loop is an undefined behavior.[2]
My suggestions is using either one of the following:
vector <student*> library_stnd and library_stnd.push_back(temp)
vector <student*> library_stnd(n) and library_stnd[i] = temp
Another suggestion
vector<student> instead of vector<*student>, then for (auto& ep: library_stnd)
'\n' instead of endl [3]
double instead of float [4]
[1] - What is the default constructor for C++ pointer?
[2] - C++ standard: dereferencing NULL pointer to get a reference?
[3] - C++: "std::endl" vs "\n"
[4] - https://softwareengineering.stackexchange.com/questions/188721/when-do-you-use-float-and-when-do-you-use-double

File handling using classes c++

I'm doing an assignment which requires file handling in C++.Assignment is long enough to be posted here, but i have made a similar simple code to elaborate my question.The following code is not read all data from file it only read the last record
please help me to make it correct.
#include <iostream>
#include <conio.h>
#include <fstream>
#include <string.h>
//class
class medicine{
int id;
char med_name[50];
int price;
int quantity;
char date[50];
public:
void data_entery(){
//int i;char na[50];int p;int q;char da[50];
cout<<"Enter id: ";
cin>>id;
cout<<"Enter name: ";
cin>>med_name;
cout<<"Enter price: ";
cin>>price;
cout<<"Enter quantity: ";
cin>>quantity;
cout<<"Enter exp_date: ";
cin>>date;
}
void display(){
cout<<this->id<<"\t "<<this->med_name<<"\t "<<this->price<<"\t"<<this- >quantity<<"\t "<<this->date;
}
}med[10];
using namespace std;
int main (){
//writing in file
ofstream wfile("medicines.txt",ios::app|ios::binary);
wfile.seekp(0,ios::end);
int rec=wfile.tellp()/sizeof(medicine);
cout<<"there are "<<rec<<" records";
med[rec].data_entery();
wfile.write(reinterpret_cast<char *>(&med),sizeof(medicine));
wfile.close();
//reading in file
ifstream rfile("medicines.txt",ios::in|ios::binary);
rfile.seekg(0,ios::end);
rec=rfile.tellg()/sizeof(medicine);
rfile.seekg(0,ios::beg);
cout<<"there are "<<rec<<" records";
for (int k=0;k<rec;k++){
med[k].display();
}
rfile.read(reinterpret_cast<char *>(&med),sizeof(med)*rec);
rfile.close();
getch();
return 0;
}
I am assuming that your file medicines.txt is initially empty.
What you have done wrong is that you have made 10 objects of the medicine class, but you are writing only one object to the file.
What you need to do here is:
for (int i=0; i < 10; i++) {
med[i].data_entery();
wfile.write(reinterpret_cast<char *>(&med),sizeof(medicine));
}
wfile.close();
Now you'll need to add 10 medicines, after details of each medicine has been added, that medicine will be written to the file.
I hope this helps.
Here is a better version of your code
#include <iostream>
#include <conio.h>
#include <fstream>
#include <string.h>
using namespace std;
//class
class medicine
{
int id;
char med_name[50];
int price;
int quantity;
char date[50];
public:
void data_entery()
{
//int i;char na[50];int p;int q;char da[50];
cout<<"\nEnter id: ";
cin>>id;
cout<<"Enter name: ";
cin>>med_name;
cout<<"Enter price: ";
cin>>price;
cout<<"Enter quantity: ";
cin>>quantity;
cout<<"Enter exp_date: ";
cin>>date;
}
void display()
{
cout<<"\nID :"<<this->id<<"\nName :"<<this->med_name<<"\nPrice :"<<this->price<<"\nQuantity :"<<this->quantity<<"\nExp Date :"<<this->date<<"\n";
}
}med;
int main ()
{
//writing in file
ofstream wfile("medicines.txt",ios::app|ios::binary);
wfile.seekp(0,ios::end);
int rec=wfile.tellp()/sizeof(medicine);
cout<<"\nthere are "<<rec<<" records";
med.data_entery();
wfile.write(reinterpret_cast<char *>(&med),sizeof(medicine));
wfile.close();
//reading in file
ifstream rfile("medicines.txt",ios::in|ios::binary);
rfile.seekg(0,ios::end);
rec=rfile.tellg()/sizeof(medicine);
rfile.seekg(0,ios::beg);
cout<<"\nthere are "<<rec<<" records";
while(rfile.read(reinterpret_cast<char *>(&med),sizeof(med)))
{
med.display();
}
rfile.close();
getch();
return 0;
}
Now, when you are using files, you do not need to create an array of objects. Once you store the object into the file, you can just reuse that object. The data can be accessed from the File. That is what I have done in this code. I have edited this code in such a manner as to not change your method, instead just corrected the problems and also made your code a little better. In each run of this code, you enter the details of one record, and then the details of all the records are shown.
The good thing about this code is, you can enter as many records as you want. You are not restricted to 10 records like your original code.