简体   繁体   中英

C++ weird cin.ignore behaviour

i'm trying to build a sample app for my students which should demonstrate how to enter multiple c-strings using cin.getline and cin.ignore but i'm getting weird results. in my code below there are two commented cin.ignore statements. if i uncomment first one then in runtime it is required to press Enter twice to input the first string and only once to input the second. if i uncomment second one instead then both strings inputted with one Enter but second string somehow lose first letter.

#include <iostream>
using namespace std;

struct Unit{
    int uid;
    char* name=new char[50];
    char* shname=new char[10];
};

int main() {
    Unit u;
    cout << "Record number: ";
    cin >> u.uid;
    cout << "Unit name: ";
    cin.ignore();
    cin.getline(u.name,50);
    //cin.ignore();
    cout << "Unit short name: ";
    //cin.ignore();
    cin.getline(u.shname,10);
    cout << "Record number: " << u.uid << endl
         << "Unit name: " << u.name << endl
         << "Unit short name: " << u.shname << endl;
    return 0;
}

i cant quite understand what am i doing wrong

cin.ignore() ignores only one character, no matter if it is white space or not.

I guess you want to ignore until the first non-white character.

For example:

while (iswspace(cin.peek()))
   cin.ignore();

And as said in the comment, getline will read also the end of line. you need to ignore it after use the stream operator ( >> ) because then it stop before the end of line and the first getline will read just the new line.

You'll need to understand why it is sometimes necessary to use ignore() ! The built-in formatted input pperations ( operator>>() ) use any space chararcter as a separator which is not extracted. On the other hand, getline() scans the input for the first occurance of the newline character (by default '\\n' ) and stores and stores and extracts all those characters. It finishes with extracting the newline character (the variation you are using also has a size constraint; I'd recomend using std::string with the non-memeber std::getline() ).

The net effect is that after a formatted input function the next character in the buffer is a separating space. When intaracting with a user using the standard input it is most likely a newline character which causes a following getline() to immediately finish. Thus, it is common that these space characters are extract, preferably using in >> std::ws rather than in.ignore() to deal with other stray space characters. After using getline() there is generally no need to skip any characters as the newline is already extracted. Put differently: the commented ignore() s are best removed.

Also, make sure you always verify the input was successful after trying to read! The vaste majority of errors with inout are due to no checking (as is the case in the code you posted) or checking before the input operations. Learning to check afterwards is sufficiently important that the argument of “making the code simple” doesn't hold: it isn't making the code simple but plain wrong!

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