Sign in to follow this  
BaldPython

getline() problem

Recommended Posts

Hello, I've been making a very basic database of student records, i am having trouble making this
Input() function
... I am using Borland C++ Builder V.5.5 and its showing me that there's some error with the use of getline function. I have also tried
cin.getline()
but it skips the name input and ask for address and then asks me the batch :-\ ... Here's the code for that function:
void DataBase::Input()
{
	cout 	<< "Enter Roll Number";
	cin	>> STD->roll_no;
	cout	<< "Enter Student name :";
	getline(cin,STD->name);
	cout 	<< "Enter your address :";
	getline(cin,STD->address);
	cout	<< "Enter Your Batch :";
	cin	>> STD->batch;
}


and if you want to know about the structure of this program, then here's the code for this full program:
#include<iostream>
#include<cstdlib>
#include<cctype>
#include<iomanip>
#include<cstring>
using namespace std;

struct student{
	unsigned int	roll_no;
	unsigned char 	name[20];
	unsigned char 	address[20];
	char  		ad_date[20];
	unsigned int	batch;
	unsigned int 	fees;
	unsigned int	dues;
	
	student* 	nextStudent;
};

struct DataBase
{
	unsigned int counter;
	struct student *STD;
	
	student* 	initialize();
	student* 	getnextstudent();
	student* 	getStudent();

	unsigned int 	getRollNumber();
	unsigned int 	getBatch();
	unsigned int 	getFee();
	unsigned char* 	getAddress();
	unsigned char* 	getstudentName();			
	unsigned int	numberOfRecords(){ return counter; }
	void	Print();
	void	Input();
};

student* DataBase::initialize()
{
	STD = new struct student;
	STD->roll_no = 0;
	STD->name[0]= '\0';
	STD->address[0] = '\0';
	STD->ad_date[0] ='\0';
	STD->batch = 0;
	STD->fees = 0;
	STD->dues = 0;
	counter =0;
	return STD;
}	

student* DataBase::getStudent()
{
	return STD;
}

student* DataBase::getnextstudent()
{
	counter++;
	STD = STD->nextStudent;
	initialize();
	return STD;
}


unsigned char* DataBase::getstudentName()
{
	return STD->name;
}

unsigned int DataBase::getRollNumber()
{
	return STD->roll_no;
}

unsigned char* DataBase::getAddress()
{
	return STD->address;
}

unsigned int DataBase::getFee()
{
	return STD->fees;
}

unsigned int DataBase::getBatch()
{
	return STD->batch;
}

void DataBase::Print()
{
	
	cout 	<< endl
		<< "Studnet Roll Number is\t:" 
		<<  STD->roll_no << endl
		<< "Student Name is \t:" 
		<<  STD->name << endl
		<<  "Student address  is\t:" 
		<<  STD->address << endl
		<< "Student Batch  is\t:" 
		<<  STD->batch << endl;
}

void DataBase::Input()
{
	cout 	<< "Enter Roll Number";
	cin	>> STD->roll_no;
	cout	<< "Enter Student name :";
	getline(cin,STD->name);
	cout 	<< "Enter your address :";
	getline(cin,STD->address);
	cout	<< "Enter Your Batch :";
	cin	>> STD->batch;
}
int main()
{	
	DataBase *D1;
	D1->initialize();
	D1->Input();
	D1->Print();
	D1->getnextstudent();
	D1->Input();
	D1->Print();

	return 0;
}


Share this post


Link to post
Share on other sites
Mixing input with >> and getline() is asking for trouble.

You can do cin >> ws; before calling getline() which will remove all whitespace including newlines in the inputbuffer. getline() will then do what you expect (most of the time).

Share this post


Link to post
Share on other sites
Lucky for you, this is a common problem [grin].

When you use a stream's extraction operator (cin >> something), it reads until the first whitespace character. In the case of a console application, for example, once you press Enter, it will read until the first space, tab, or newline constant.

getline does the same thing, except it will generally be reading all the way to the newline.

The difference is that when '>>' gets to whitespace, it stops and returns what it's read so far, whereas getline also discards that whitespace from the stream.

As a side effect, if the first character in the stream is whitespace (like the newline constant that 'cin >> ...' left in the stream, it will immediately return a blank string.

What you want to do is call cin.ignore() after you use '>>' and before you use getline. This will throw out that newline constant that was left in the stream, so getline can read the full next line.

So this is what your code would look like.


void DataBase::Input()
{
cout << "Enter Roll Number";
cin>> STD->roll_no;
cout<< "Enter Student name :";
cin.ignore(); // cin >> STD->roll_no probably left whitespace
getline(cin,STD->name);
cout << "Enter your address :";
getline(cin,STD->address); // No ignore is necessary because cin >> has not been used since the last getline
cout<< "Enter Your Batch :";
cin>> STD->batch;
}


Share this post


Link to post
Share on other sites
The free function getline operates on std::string objects, not raw char arrays. You want either:
void DataBase::Input()
{
cout << "Enter Roll Number";
cin >> STD->roll_no;
cout << "Enter Student name :";

// sync the stream to get rid of unextracted characters
cin.sync();

// use get not getline and pass the size of the array so that we can
// correctly deal with overly long input without suffering a buffer overflow
cin.get(STD->name, sizeof(STD->name), '\n');

// ignore any extra input
cin.ignore(numeric_limits< streamsize >::max(), '\n');

cout << "Enter your address :";
cin.get(STD->address, sizeof(STD->address), '\n');
cin.ignore(numeric_limits< streamsize >::max(), '\n');
cout << "Enter Your Batch :";
cin >> STD->batch;
}

Or, more probably:
struct student{
unsigned int roll_no;
string name;
string address;
string ad_date;
unsigned int batch;
unsigned int fees;
unsigned int dues;

student* nextStudent;
};

void DataBase::Input()
{
cout << "Enter Roll Number";
cin >> STD->roll_no;
cout << "Enter Student name :";
cin.sync();
getline(cin,STD->name);
cout << "Enter your address :";
getline(cin,STD->address);
cout << "Enter Your Batch :";
cin >> STD->batch;
}

Which has the advantage of allowing any length name and address. I'll ignore for now the fact that you almost certainly ought to be using std::list instead of building a list structure into your student class.

Enigma

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this