Problem in accepting a blank space to string in c++ - c++

I wrote this code to obtain name. telephone and address of a person and then i input these into class object variables:
#include<iostream>
#include<cstdlib>
#include<fstream>
#include<string>
using namespace std;
class contact{
public:
string name;//ALL CLASS VARIABLES ARE PUBLIC
unsigned int phonenumber;
string address;
contact(){//Constructor
name= "Noname";
phonenumber= 0;
address= "Noaddress";
}
/*void input_contact_name(string s){//function to take contact name
name=s;
}
void input_contact_number(int x){//function to take contact number
phonenumber=x;
}
void input_contact_address(string add){//function to take contact address
address=add;
}*/
};
int main(){
contact *d;
d= new contact[200];
string name,add;
int choice;//Variable for switch statement
unsigned int phno;
static int i=0;//i is declared as a static int variable
bool flag=false;
cout<<"\tWelcome to the phone Directory\n";//Welcome Message
cout<<"Select :\n1.Add New Contact\n2.Update Existing Contact\n3.Delete an Existing Entry\n4.Display All Contacts\n5.Search for a contact\n6.Exit PhoneBook\n\n\n";//Display all options
cin>>choice;//Input Choice from user
while(!flag){//While Loop Starts
switch(choice){//Switch Loop Starts
case 1:
cout<<"\nEnter The Name\n";
cin>>name;
d[i].name=name;
cout<<"\nEnter the Phone Number\n";
cin>>phno;
d[i].phonenumber=phno;
cout<<"\nEnter the address\n";
cin>>add;
d[i].address=add;
i++;
flag=true;
}
}
return 0;
}
However If I enter the name separated with its surname, the code bypasses the next cins and exits. Can some one help me out why this happens?
Same happens when I enter 10 digit cell no.
Thanks in advance

Use std::getline() instead of operator>> to extract a std::string containing whitespace.

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

How to fix this string validation (Telephone directory system)

Im talking about the string validation in void enter() , what im trying to do is create a system , where if someone accidentally puts a number in Enter name field , they need to write it again
im just not being able to solve this string validation at all.
I tried something like
after cout<<"Enter name";
for(int i=0;i<strlen(name);i++)
{
gets(name);
if(isalpha(name[i]))
cout<<"There is a number in the input , try again";
}
include<fstream.h>
include<stdio.h>
include<conio.h>
include<string.h>
include<stdlib.h>
class Directory
{
char name[20];
char num[30];
char address[50];
public:
void enter()
{
cout<<"Enter name: "<<endl;
gets(name);
cout<<"Enter number: "<<endl;
gets(num);
cout<<"Enter address: "<<endl;
gets(address);
}
it did work , but if I enter a name "mar3", now i have to enter Mark four times for it to take the record.
I think this is what you want to do. You want to reenter the name untill it meets your requrement.
bool validate(char name[])
{
for(int i=0;i<strlen(name);i++)
if(isalpha((unsigned char)name[i]))
{
cout<<"There is a number in the input , try again";
return 0;
}
return 1;
}
and while reading name do this.
gets(name);
while(!validate(name))
{
gets(name);
}
UPD :
use string and getline to read.
#include<fstream>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<stdio.h>
#include<iostream>
using namespace std;
bool validate(string name)
{
for(int i=0;i<name.length();i++)
if(isalpha(name[i]))
{
cout<<"There is a number in the input , try again\n";
return 0;
}
return 1;
}
class Directory
{
string name,num,address;
public:
void enter()
{
cout<<"Enter name: "<<endl;
getline(cin,name);
while(!validate(name))
{
getline(cin,name);
}
cout<<"Enter number: "<<endl;
getline(cin,num);
cout<<"Enter address: "<<endl;
getline(cin,address);
}
};
here is you want to also limit the length of the name or number you can make another validator for that

getline (cin, string) is not excuted last line of code

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.

Updating objects with getline doesn't seem to work

I'm having odd behavior when creating and using a class.
I create multiple instances of that class, sequentially - and then I create a few temp variables to prompt the user to enter some data, then i use basic mututaor functions and pass the data to the parts of the object. I do this for the first item, then the second, etc.
What happens when the declarations of those personalData elements are sequential then for some reason the cin/getline statements skip over some and i can't enter all the data correctly. When i spread them out between statements have one object created then the input from the user then updates, then the next object it works better but still not in 100% of the cases. Lastly i found that creating different variables for inputting data - my temp variables also resolves the problem but that seems strange to have to create a dozen variables when i should be able to input data/update existing ones?
class personalData
{
private:
string name;
string address;
int phone;
int age;
public:
void setname(string);
void setadress(string);
void setphone(int);
void setage(int);
string getname()const;
string getadress()const;
int getage()const;
int getphone()const;
};
void personalData::setname(string n)
{ name=n; }
void personalData::setadress(string a)
{ address=a; }
void personalData::setphone(int p)
{ phone=p;}
void personalData::setage(int ag)
{age=ag;}
string personalData::getname()const
{return name;}
string personalData::getadress()const
{return address;}
int personalData::getage()const
{return age;}
int personalData ::getphone()const
{return phone;}
int main()
{
personalData my;
personalData friendd;
personalData family;
string n;
string a;
int p;
int g;
cout<<"enter your name";
getline(cin,n);
cout<<"enter your address:";
getline(cin,a);
cout<<"enter your phone:";
cin>>p;
cout<<"enter your age";
cin>>g;
my.setname(n);
my.setadress(a);
my.setphone(p);
my.setage(g);
cout<<"enter your friend's name";
getline(cin,n);
cout<<"enter your friend's address:";
getline(cin,a);
cout<<"enter your friend's phone:";
cin>>p;
cout<<"enter your friend's age";
cin>>g;
friendd.setname(n);
friendd.setadress(a);
friendd.setphone(p);
friendd.setage(g);
cout<<"enter your family member's name";
getline(cin,n);
cout<<"enter your family member's address:";
getline(cin,a);
cout<<"enter your family member's phone:";
cin>>p;
cout<<"enter your family member's age";
cin>>g;
family.setname(n);
family.setadress(a);
family.setphone(p);
family.setage(g);
cout<<"my name"<<my.getname()<<endl;
cout<<"my address"<<my.getadress()<<endl;
cout<<"my phone"<<my.getphone()<<endl;
cout<<"my age"<<my.getage()<<endl;
// more cout statements with objects.getData ...
return 0;
}
Sorry for the long piece of code, I'm stuck and can't figure out what the issues are.
Thanks.