1,105,633 Community Members

cannot accept strings into a structure

Member Avatar
aashishsatya
Newbie Poster
5 posts since Jan 2012
Reputation Points: -4 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

I was trying to input strings into a structure I made, but I couldn't succeed. I use Visual C++ 2010 Express Edition.
The code is this:

#include<iostream>
#include<conio.h>
#include<stdio.h>
#include<string.h>
using namespace std;
struct schrec
{
	char childname[20];
	int childage;
};
void main()
{
	schrec record[20];
	int n;
	cout<<"How many students?\n";
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cout<<"Enter name of student "<<i+1<<endl;
		gets(record[i].childname);
		cout<<"Enter age of the student\n";
		cin>>record[i].childage;
	}
	cout<<"\nThe record you gave is";
	for(int i=0;i<n;i++)
		cout<<endl<<record[i].childname<<" ("<<record[i].childage<<")\n";
	_getch();
}

The output in Visual C++ is

How many students?
1
Enter name of student 1
Enter age of the student
15
The record you gave is
(15)

But when I compile this in Borland C++ v4.5 (with necessary changes like removing namespace std, system("cls") to clrscr() etc) it works fine.
What can I do to overcome the problem?
Thanks in advance...

Member Avatar
NathanOliver
Posting Virtuoso
1,657 posts since Apr 2009
Reputation Points: 284 [?]
Q&As Helped to Solve: 310 [?]
Skill Endorsements: 4 [?]
 
2
 

After line 16 add cin.ignore(); . This is beacuse you are mixing inputs and this will clear the '/n' that is left in the buffer after the call to cin with >> . Not 100% sure how gets() works but this fixes the problem when trying to use getline()

Member Avatar
jaskij
Junior Poster
105 posts since Oct 2011
Reputation Points: 45 [?]
Q&As Helped to Solve: 19 [?]
Skill Endorsements: 0 [?]
 
0
 

1. The problem you have is gets catches the EOL you get after hitting return for the number of the kids. Adding something like getch() before that gets() should fix this. Or just use gets() twice.

2. Use string instead of string.h - the second one is legacy AFAIK.

3. Don't mix C++ and C I/O. Use istream::getline() or getline() from the string library.

Member Avatar
aashishsatya
Newbie Poster
5 posts since Jan 2012
Reputation Points: -4 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

Thanks! The program works fine now. Can you explain what you mean when you say "mixing inputs and this will clear the '\n' that is left in the buffer after the call to cin with >> ".
And how come I've never had this problem before (I've written many programs that use a '\n' after accepting the number of numbers)?

After line 16 add cin.ignore(); . This is beacuse you are mixing inputs and this will clear the '/n' that is left in the buffer after the call to cin with >> . Not 100% sure how gets() works but this fixes the problem when trying to use getline()

Member Avatar
Lerner
Nearly a Posting Maven
2,416 posts since Jul 2005
Reputation Points: 579 [?]
Q&As Helped to Solve: 407 [?]
Skill Endorsements: 16 [?]
 
1
 

Input in C++ is buffered. That means that when you type stuff on the keyboard it is stored in an internal "buffer----think array or queue" until input is terminated, usually by entering a new line char by hitting the enter key. The input waits in the buffer until an input function (method) access the input buffer. cin >> , gets() and getline() are all examples of input functions (methods). >> terminates input into the object on the right hand side of >> when it finds the first whitespace char (space char, new line char, tab, etc) and it leaves the terminating char in the input buffer. gets() terminates input into the object enclosed in the () when it identifies a new line char or the EOF marker in the input buffer. getline() terminates input into the associated string when the delimiting char is encountered and it removes the terminating char from the input buffer. (The default delimiting char for getline() is the new line char).

In your program you call cin >> before you call gets(). cin >> leaves the terminating new line char in the input buffer. When you call gets() the first thing it sees is the new line char in the input buffer left by preceding call to cin >>. It therefore thinks you don't want to put anything into whatever is in the () so whatever it is is left empty, or looks like it is skipped. To deal with this problem either call the ignore() function using appropriate syntax to ignore (remove) just the first char in the input buffer before you call gets() OR don't mix input methods like cin >> and gets() or cin >> and getline(), etc, in the same program.

Member Avatar
WaltP
Posting Sage w/ dash of thyme
9,363 posts since May 2006
Reputation Points: 2,905 [?]
Q&As Helped to Solve: 1,151 [?]
Skill Endorsements: 45 [?]
Team Colleague
 
2
 

1. The problem you have is gets catches the EOL you get after hitting return for the number of the kids. Adding something like getch() before that gets() should fix this. Or just use gets() twice.

Using gets() at all is dangerous -- here's why. And gets() "does not catch" (whatever that means) the EOL. getch() is a completely non-portable solution and exists in very few compilers. It's best to learn proper techniques because learning to use gets() and getch() will cause major problems when you start programming for real.

2. Use string instead of string.h - the second one is legacy AFAIK.

No, string.h is the header used for c-strings. string is the header used for C++ strings.

3. Don't mix C++ and C I/O. Use istream::getline() or getline() from the string library.

True. If using getline in one place, why use gets() somewhere else?

Member Avatar
jaskij
Junior Poster
105 posts since Oct 2011
Reputation Points: 45 [?]
Q&As Helped to Solve: 19 [?]
Skill Endorsements: 0 [?]
 
0
 

Guess I made a fool out of myself there. Thanks for pointing those out WaltP :)

And what I suggested at the beginning was mostly because OP used those, although I knew that :/ damn my laziness :/
What I meant by "catching" the EOL is that it stays in the buffer and that is the cause of the unintended behavior.

Question Answered as of 2 Years Ago by jaskij, Lerner, WaltP and 1 other
You
This question has already been solved: Start a new discussion instead
Post:
Start New Discussion
View similar articles that have also been tagged: