简体   繁体   中英

It seems to me as if std::getline doesn't handle new lines correctly?

With the code below, I want the user to write a text in the terminal, and then print out the last sentence of the text. Maybe I should mention that I'm running on a Linux desktop.

#include <string>
#include <iostream> 

int main()
{
    std::string user_text{};

    while(std::getline(std::cin, user_text))
    {

    }

    std::cout << "Text: " << user_text << std::endl;

    return 0;
}

Anyways if I, after running the program, write for example:

Hi my name is

And then press 'ctrl+d', the output will indeed be "Text: Hi my name is"

However if I instead do this:

Hi my name is 'press enter'

Name my is hi 'press enter'

And then press 'ctrl+d'. The output will be "Text: " . Why is this? Shouldn't getline stop when I have pressed 'ctrl+d'?

Thanks in advance!

std::getline() erases the output std::string before attempting to read from the stream.

In your second case, the first 2 calls to std::getline() have already read everything you have typed in, there is nothing left when you press CTRL-D during the 3rd call, so there is nothing for std::getline() to output into the std::string .

Save the last successful line read to a separate variable, eg:

std::string user_text, line;

while(std::getline(std::cin, line))
{
    user_text = line;
}

std::cout << "Text: " << user_text << std::endl;

Ctrl+D causes the process's read from the terminal to return immediately. If you press Ctrl+D after typing: Hi my name is , the process will read: Hi my name is . getline will not find a \n and will restart reading. Then you press Ctrl+D a second time (you didn't say it but I am sure you did). And this will interrupt the read , causing it to return 0, which is as-if the terminal was closed. getline will then return the current value: Hi my name is .

In the second case, you haven't typed anything since the last \n , so when you press Ctrl+D , read directly returns 0 and getline returns with an empty string.

std::getline is working as intended: it's getting a line. If you press enter, it creates a new, empty line; if you then press ctrl+d, you're terminating std::getline, which returns that (empty) line's contents.

From the docs :

getline reads characters from an input stream and places them into a string:

  1. Behaves as UnformattedInputFunction, except that input.gcount() is not affected. After constructing and checking the sentry object, performs the following:
    1. Calls str.erase()
    2. Extracts characters from input and appends them to str until one of the following occurs (checked in the order listed) a) end-of-file condition on input, in which case, getline sets eofbit. b) the next available input character is delim, as tested by Traits::eq(c, delim), in which case the delimiter character is extracted from input, but is not appended to str. c) str.max_size() characters have been stored, in which case getline sets failbit and returns.
    3. If no characters were extracted for whatever reason (not even the discarded delimiter), getline sets failbit and returns.
  2. Same as getline(input, str, input.widen('\n')), that is, the default delimiter is the endline character.

Often writing std:: , its make us boring. You can use the library such as you can not right again again #include using namespace std;

Or if do not wan to concern about library You can use #include<bits/stdc++.h> using namespace std;

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