简体   繁体   中英

getline removes first character; removal of cin.ignore(); does not resolve

int main()
{
for (int i = 0; i < 4; ++i)
    {
    cout << "Please enter Employee #" << (i+1) << "'s" << " name: ";
    cin.ignore();
    getline(cin, employee[i].employeeName);
    cout << "Please enter Employee #" << (i+1) << "'s hours worked: ";
    cin >> employee[i].hoursWorked;
    cout << "Please enter Employee #" << (i+1) << "'s hourly rate: ";
    cin >> employee[i].hourlyRate;
    cout << "Please enter Employee #" << (i+1) << "'s Federal Tax Rate: ";
    cin >> employee[i].fedtaxRate;
    cout << "Please enter Employee #" << (i+1) << "'s State Tax Rate: ";
    cin >> employee[i].statetaxRate;
    cout << endl;
    }

As the title says, I currently have cin.ignore(); to help with taking in a full name like "Barkley, Charles" (it does a fine job, except it truncates the first character leaving us with "arkley, Charles" when printed) but when I remove cin.ignore(); , like 99% of the StackOverflow questions that have been answered say, nothing happens. In fact, it even gets worse: on the second loop, it will take the second line of the second loop and put it on the first line of the second loop. It's just a mess. Oh, and cin.getline doesn't work either. I tried that in conjunction with cin.sync and no dice. Regular plain old vanilla cin >> causes the same second line on first line problem. I don't know what to do. I haven't found a SO article that covers this (seemingly) edge case. Thanks for the help.

As with many input questions, the problem exists because you're mixing line-based and item-based input.

What will happen is that the final cin >> employee[i].statetaxRate; will leave the stream pointer pointing to a position immediately after the last valid character of its type.

That's likely to be the newline at the end of the line so, when you then go back to get the next name (without the cin.ignore ), it will read that as an empty line.

You may think you can fix it by placing the cin.ignore at the end of the loop but you can run into other problems with that. Specifically, since that form simply skips one character, entering:

123<space><newline>

will simply skip the <space> and you'll have exactly the same issue.

A quick fix is to simply read the entire rest of the line with something like (at the end of the loop):

{
    std::string junk;
    getline(cin, junk);
}

and this will prep the input stream so you're at the start of the next line.


The other possibility (and this is preferred since the first time you enter abc where it's expecting a number is going to cause you grief) is to read all your items as lines and then use string processing to put them into numeric variables, something like strtod() .

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