Home > database >  Why does ignore() before getline() take one less character input?
Why does ignore() before getline() take one less character input?

Time:04-19

I am using the getline() function in C , but there is a problem that the input starts from the second character. I used the ignore() function to erase what remains in the buffer first, emptying the buffer and receiving input. How can I empty the buffer and receive input properly?

image

Above is the execution result. I previously used the ignore() function and the getline() function to empty the buffer and receive input because there may be some leftovers in the buffer before.

In other programs that write like that, it also receives integer input before.

void InputValue(string *st) {
    //cin.clear();
    cin.ignore();
    getline(cin, *st);
}

int main(void) {
    string str;
    InputValue(&str);

    cout << str;
    return 0;
}

CodePudding user response:

In the beginning, immediately after input, stdin (your input buffer) contains :

abcd

Those character are waiting to be extracted in whatever manner you choose. Since you are reading from stdin (using std::cin) using getline() from the stream into a std::string, getline() will consume all characters in the line, reading and discarding the trailing '\n' with all characters stored in your std::string. There are no characters left in stdin that need to be extracted using std::cin.ignore()

When you call std::cin.ignore() before getline() you are reading (and discarding) the first character waiting to be read in stdin. With the example characters above, after calling std::cin.ignore(), and extracting and discarding the character, the following is left in stdin:

bcd

So now when you do call getline (std::cin, *st); "bcd" are the only characters that are available. That is the reason why you miss the first character.

While you can std::cin.ignore() one character, the .ignore() member function is usually used to read/discard all remaining characters in a line using the form

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

Where #include <limits> provides the constants representing the maximum number of the type specified, above <std::streamsize>::max() (e.g. the maximum value that size_t can represent). A large constant is used to ensure the remainder of the line, no matter how long, is consumed and discarded leaving std::cin either empty or with the first character of the next line (in a multi-line buffer) waiting to be read.

std::basic_istream::ignore can also read up to a delimiter character reading/discarding less than the whole line. That can be useful when reading separated fields, or in cases where you use a delimiter with getline() to read less than an entire line.

You either perform your read operation first and then call ignore() to discard unwanted characters to the end of the line, or you can call ignore() first with either a specified number of characters (default 1) or a delimiter to discard the beginning portion of a line up to the first character you want to began your read with.

As you have used it above, it will simply chop off the first character of whatever the user enters -- which does not seem to be what you want. In fact, ignore() isn't even needed above. Remove it and see if the missing character problem doesn't go away.

  •  Tags:  
  • c
  • Related