Cannot get the "getline()" function to work in a loop

For some reason I cannot get the "getline()" function to work in a loop(lines 33, 54-60). When running the program: After the first time through the loop, the program passes over the getline function (as if it already has input) and goes right to the next input line. I have tried using cin.ignore() and it solves the problem of the program passing over the getline function, however, when I print (line 46, 93-97) the variable that getline writes to, it drops the first letter. Anyone have any suggestions on how to get passed this?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
 
#include "stdafx.h"
#include <string>
#include <iostream>
#include <iomanip>
using namespace std;

struct Player
	{
		string name;
		int number;
		int points;
	};

void getPlayerInfo(Player&);
int ValidateScores(int);
int ValidateNumbers(int);
void showInfo(Player);
string setLength (string, int, char);

int main()
{
	const int team = 3;
	Player Roster[team];
	Player Info; 
	Player PInfo;

cout<<"Enter Player Information:" <<endl;
	
      //Loops the getPlayerInfo function
        //and then copies the input to the 
        //array Roster for each player
	for(int i=0; i<team; i++)
	{
	 cout<<"Player # "<<(i+1)<<endl;
	 cout<<"------------"<<endl;
	 getPlayerInfo(Info);
	 Roster[i] = Info;
	}
	
	cout<< "NAME" << setw(22)<< "NUMBER" << setw(18) << "POINTS SCORED" <<endl;
	
      //Loops the array to copy the information
        //in each element to the variable PInfo
        //and prints each element 
        for(int i=0; i<team; i++)
	{
	 PInfo = Roster[i];
	 showInfo(PInfo);
	}

}
//*********Functions******************
void getPlayerInfo(Player &teamMember)
{       
     //Here is where I am having the issues
	cout<<"Player's name: "; 
	cin.ignore();
	getline(cin,teamMember.name);
	
	cout<<"Player's number: ";
	cin>>teamMember.number;
	teamMember.number = ValidateNumbers(teamMember.number);
	cout<<"Points scored: ";
	cin>>teamMember.points;
	teamMember.points = ValidateScores(teamMember.points);
	cout<<endl;
	
}

int ValidateNumbers(int numbers)
{
	while (numbers < 0)
	{ 
		cout<< "\tPlayer's numbers cannot be negative." <<endl;
		cout<< "\t\tPlease try again" <<endl;
		cout<< "Player's number:"; cin>>numbers;
	}
	return numbers;
}

int ValidateScores(int points)
{
	while (points < 0)
	{ 
		cout<< "\tPoints scored cannot be negative." <<endl;
		cout<< "\t\tPlease try again" <<endl;
		cout<< "Points scored :"; cin>>points;
	}
	return points;
}

void showInfo(Player teamMember)
{
	
	cout<< setLength(teamMember.name, 21, ' ')  <<setw(2)<<  teamMember.number<< setw(18) << teamMember.points<<endl;
}

string setLength (string name, int n, char c = ' ' )// Copies the required amount of letters from 
{                                                   // name. If there are too  many, they will
	                                                // be cut off. If there are too little, the rest
	string formName(n, c);                          // will be spaces.

	for (int i = 0; i < n && i < name.size(); i++)
	{
		formName[i] = name[i];
	}
	return formName;
}
Last edited on
Use cin.ignore(); right after cin >> whatever;, not right before getline(cin, whateverelse);.

The problem comes from the fact that cin >> whatever; leaves a newline in the input buffer, which gets eaten by getline instead of whatever your input is supposed to be. So cin.ignore(); is needed to get rid of that newline character.

If the input buffer is already empty (which is the case on line 58 the first time), then blinding calling cin.ignore(); before your getline will cause cin to throw out the first character of your input instead of the newline character that you want it to throw out.
Tried putting <cin.ignore();> after and on the second time through the loop the program skipped the second input line and went to the third. Is there as way to empy the buffer after the string has been copied to the array element so that in the next loop the buffer is empty?

P.s How do you get the code to appear in blue like that?
As far as I can tell, the only change you need to make is this:
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
void getPlayerInfo(Player &teamMember)
{       
    //Here is where I am having the issues
    cout<<"Player's name: "; 
    //cin.ignore(); // Not here <----------------
    getline(cin,teamMember.name);
    
    cout<<"Player's number: ";
    cin>>teamMember.number;
    teamMember.number = ValidateNumbers(teamMember.number);
    cout<<"Points scored: ";
    cin>>teamMember.points;
    cin.ignore(); // Clear out the newline here <-------------
    teamMember.points = ValidateScores(teamMember.points);
    cout<<endl;
    
}

And as for your last question, use [code][/code] tags.
So [code]int a;[/code] shows up as int a;.
Brilliant! I know that this seems like an obvious answer (i feel like I should have been able to figure it out) but I really needed another brain working on this because mine sure wasn't. Thank you!

And thanks for the info on code tags!
If you're mixing formatted and unformatted extraction, and you don't need getline to capture leading whitespace (or empty lines,) the easiest solution is to just insert:

std::cin >> std::ws ;

before any uses of getline. In fact, making a function of your own to automate it would probably be a good idea:

1
2
3
4
5
std::istream& mygetline(std::istream&is, std::string& str)  // skips empty lines
{
    is >> std::ws ;
    return std::getline(is,str);
}
Topic archived. No new replies allowed.