Reputation: 77
I'm sure there's a newbie mistake here, but I can't for the life of me figure it out.
I'm trying to use getline()
to read a two word line (first and last names), and then sort the names into member fields of a struct. However, getline()
seems to be rolling past the end of the lines and appending the first word of the next line to the last word of the line it should be getting.
In other words, when trying to read the last word of a line, getline()
is reading that word and the first word of the next line.
The input file is of the form:
Seattle Mariners
Norichiki Aoki
Seth Smith
Robinson Cano
Here's my code:
struct Player {
string firstName;
string lastName;
float avg;
};
struct Team {
Player roster[8];
string teamName;
};
Team home = {};
stringstream iss;
string token;
string lineread;
while (getline(inFile, lineRead, '\n')){
iss << lineRead;
if (getline(iss, token, ' '))
{
if(s % 2 == 0)
home.roster[s/2].firstName = lineRead;
else
home.roster[s/2].lastName = lineRead;
}
s++;
cout << "token:" << token << endl;
}
The output I'm getting looks like this:
token: Seattle
token: MarinersNorichiki
token: AokiSeth
token: SmithRobinson
But I would like to have
token: Seattle
token: Mariners
token: Norichiki
token: Aoki
Upvotes: 1
Views: 9109
Reputation: 754
std::cin.getline() can run into problems when used with std::cin >> var.
getline can be provided a third argument--a "stop" character. This character ends getline's input. The character is eaten and the string is terminated. Example: std::cin.getline(str, 100, '|') If std::cin.getline() is not provided a "stop" character as a third argument, it will stop when it reaches a newline. Given:
float fl;
std::cin >> fl;
char str[101]
std::cin.getline(str, 101);
And you type: 3.14
3.14 is read into fl . The newline following the 3.14 is still sitting on the input buffer. std::cin.getline(str, 101) immediately processes the newline that is still on the input buffer. str becomes an empty string. The illusion is that the application "skipped" the std::cin.getline() statement.
The solution is to add std::cin.ignore(); immediately after the first std::cin statement. This will grab a character off of the input buffer (in this case, newline) and discard it.
std::cin.ignore() can be called three different ways:
Upvotes: 3
Reputation: 596833
Try something more like this instead:
struct Player {
string firstName;
string lastName;
float avg;
};
struct Team {
Player roster[8];
string teamName;
};
Team home = {};
int s = 0;
string line;
while (getline(inFile, line))
{
istringstream iss(line);
iss >> home.roster[s].firstName;
iss >> home.roster[s].lastName;
home.roster[s].avg = ...;
cout << "first: " << home.roster[s].firstName << ", last: " << home.roster[s].lastName << endl;
if (++s == 8) break;
}
Upvotes: 0