简体   繁体   中英

C++ getline() not stopping at the end of line?

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

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:

  1. No arguments: A single character is taken from the input buffer and discarded: std::cin.ignore(); //discard 1 character
  2. One argument: The number of characters specified are taken from the input buffer and discarded: std::cin.ignore(33); //discard 33 characters
  3. Two arguments: discard the number of characters specified, or discard characters up to and including the specified delimiter (whichever comes first): std::cin.ignore(26, '\\n'); //ignore 26 characters or to a newline, whichever comes first

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM