I have the following simple program, but the last line of code getline(cin, topicClass) is never excuted. However, if I use normal cin>>topicClass that is executed. Could you please help me out of this? Thanks
#include <iostream>
#include <string>
using namespace std;
void InfoInput()
{
string classID;
string teacherName;
int totalStudent;
string topicClass;
cout<<"Enter class ID"<<endl;
getline(cin, classID);
cout<<"Enter teacher's name"<<endl;
getline(cin, teacherName);
cout<<"Enter total number of students"<<endl;
cin>>totalStudent;
cout<<"Enter topic of class"<<endl;
getline(cin, topicClass);
//cin>>topicClass;
}
int main ()
{
InfoInput();
}
Your problem is above, with this line:
cin>>totalStudent;
This does not read a line. You enter your input and (I assume) you press ENTER. The \n remains in the buffer of std::cin and is read as an empty line with your next instruction:
getline(cin, topicClass);
To fix, use this code:
cin>>totalStudent;
while(std::isspace(cin.peek())
cin.ignore();
cout<<"Enter topic of class"<<endl;
getline(cin, topicClass);
There is \n remained in cin after reading totalStudent as integer so you need to get that \n first out of the system and then read the next string
#include <iostream>
#include <string>
using namespace std;
void InfoInput()
{
string classID;
string teacherName;
int totalStudent;
string topicClass;
cout<<"Enter class ID"<<endl;
getline(cin, classID);
cout<<"Enter teacher's name"<<endl;
getline(cin, teacherName);
cout<<"Enter total number of students"<<endl;
cin>>totalStudent;
cout<<"Enter topic of class"<<endl;
getline(cin,topicClass);
getline(cin, topicClass);
//cin>>topicClass;
}
int main ()
{
InfoInput();
}
Your classID and teacherName are local variables and disappear after execution leaves the function. You'll have to figure out some way, like passing parameters by reference, to share the variables between functions.
Related
This question already has answers here:
getline() does not work if used after some inputs [duplicate]
(3 answers)
Closed 1 year ago.
In the following code, I have made two classes, the second class is inherited from the first one. However when I call the getdata function. it skips input, I have tried using cin.ingnore() and also cin>>ws, but I am still getting the same errors. It runs properly till " Enter the Last name" but after that, it just prints all the other things without taking the input.
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
class RegistrationModule{
protected:
string Firstname;
string Lastname;
double cnic;
double contact;
string address;
static double challanno;
public:
RegistrationModule(){
Firstname = "";
Lastname = "";
cnic=0;
address = "";
contact=0;
challanno++;
}
};
double RegistrationModule::challanno=105487;
class monthlyentry : public RegistrationModule{
public:
void getdata(){
cout<<"Enter First Name"<<endl;
getline(cin,Firstname);
cin.ignore();
cout<<"Enter Last Name"<<endl;
getline(cin,Lastname);
cin.ignore();
cout<<"Enter your CNIC: "<<endl;
cin>>cnic;
cin.ignore();
cout<<"Enter your Address: "<<endl;
getline(cin,address);
cout<<"Enter your contact number: "<<endl;
cin>>contact;
cout<<"Your Challan Number is: "<<challanno<<endl;
}
};
int main(){
int size;
monthlyentry a;
a.getdata();
}
You cannot just slap ignore() randomly and expect things to work. By default, ignore() will remove 1 character. If there is no character there, it will set eof() bit and your stream cannot read anything more until you clear() eof flag from it.
Only use ignore() when there is a leftover end of line (like after formatted extraction).
void getdata(){
cout<<"Enter First Name"<<endl;
getline(cin,Firstname);
cout<<"Enter Last Name"<<endl;
getline(cin,Lastname);
cout<<"Enter your CNIC: "<<endl;
cin>>cnic;
cin.ignore();
cout<<"Enter your Address: "<<endl;
getline(cin,address);
cout<<"Enter your contact number: "<<endl;
cin>>contact;
cin.ignore(); // might want to clear up before next extractions
cout<<"Your Challan Number is: "<<challanno<<endl;
}
To use std::ws, you would need to use directly in getline calls
std::getline(std::cin >> std::ws, Firstname);
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);
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.
See the below code. If i give a "space" input for variable name, another integer variable is not being stored in the file. Why?
I've posted the outputs too.
#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;
int main()
{
int age;
char name[100];
ofstream obj,obj10;
obj.open("lol.dat", ios::trunc);
cout<<"Enter Name"<<endl;
cin.getline(name,100);
cin.ignore();
obj<<name<<endl;
cout<<"Enter age"<<endl;
cin>>age;
cin.ignore();
obj10<<age<<endl;
obj.close();
//read
ifstream obj2;
obj2.open("lol.dat");
obj2>>name;
cout<<"Name:"<<name<<endl;
obj2>>age;
cout<<"Age:"<<age<<endl;
obj2.close();
return 0;
}
My outputs:
Enter Name
Ankith
Enter age
1234
Name:Ankith
Age:1234
Enter Name
Ankith Prabhas
Enter age
12345
Name:Ankith
Age:0
What do i need to do to take the complete name "Ankith Prabhas" as one input and another integer?
Try to use getline() in strings where you expect spaces.
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.