在我看来,好像 std::getline 没有正确处理新行?
It seems to me as if std::getline doesn't handle new lines correctly?
使用下面的代码,我希望用户在终端中写一段文字,然后打印出该文字的最后一句话。也许我应该提到我 运行 在 Linux 桌面上。
#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;
}
无论如何,如果我在 运行 程序之后,写例如:
Hi my name is
然后按'ctrl+d',输出确实是"Text: Hi my name is"
但是,如果我改为这样做:
Hi my name is 'press enter'
Name my is hi 'press enter'
然后按'ctrl+d'。输出将是 "Text: "
。为什么是这样?当我按下 'ctrl+d' 时,getline 不应该停止吗?
提前致谢!
std::getline()
在尝试从流中读取之前擦除输出 std::string
。
在你的第二种情况下,前两次调用 std::getline()
已经读取了你输入的所有内容,当你按下 CTRL-D第三次调用,所以 std::getline()
没有任何输出到 std::string
.
将最后一次成功读取的行保存到一个单独的变量中,例如:
std::string user_text, line;
while(std::getline(std::cin, line))
{
user_text = line;
}
std::cout << "Text: " << user_text << std::endl;
Ctrl+D
导致进程的 read
从终端立即到 return。如果您在键入 Hi my name is
后按 Ctrl+D
,该过程将读取:Hi my name is
。 getline
将找不到 \n
并将重新开始阅读。然后您再次按 Ctrl+D
(您没有说,但我确定您说了)。这将中断 read
,导致它变为 return 0,就好像终端已关闭一样。 getline
将 return 当前值:Hi my name is
.
在第二种情况下,自从上次\n
之后你没有输入任何内容,所以当你按Ctrl+D
时,read
直接returns 0和getline
returns 为空字符串。
std::getline
正在按预期工作:它正在排队。如果你按下回车键,它会创建一个新的空行;如果您随后按 ctrl+d,您将终止 std::getline,即 returns 该(空)行的内容。
来自docs:
getline reads characters from an input stream and places them into a string:
- Behaves as UnformattedInputFunction, except that input.gcount() is not affected. After constructing and checking the sentry object, performs the following:
- Calls str.erase()
- 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.
- If no characters were extracted for whatever reason (not even the discarded delimiter), getline sets failbit and returns.
- Same as getline(input, str, input.widen('\n')), that is, the default delimiter is the endline character.
使用下面的代码,我希望用户在终端中写一段文字,然后打印出该文字的最后一句话。也许我应该提到我 运行 在 Linux 桌面上。
#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;
}
无论如何,如果我在 运行 程序之后,写例如:
Hi my name is
然后按'ctrl+d',输出确实是"Text: Hi my name is"
但是,如果我改为这样做:
Hi my name is 'press enter'
Name my is hi 'press enter'
然后按'ctrl+d'。输出将是 "Text: "
。为什么是这样?当我按下 'ctrl+d' 时,getline 不应该停止吗?
提前致谢!
std::getline()
在尝试从流中读取之前擦除输出 std::string
。
在你的第二种情况下,前两次调用 std::getline()
已经读取了你输入的所有内容,当你按下 CTRL-D第三次调用,所以 std::getline()
没有任何输出到 std::string
.
将最后一次成功读取的行保存到一个单独的变量中,例如:
std::string user_text, line;
while(std::getline(std::cin, line))
{
user_text = line;
}
std::cout << "Text: " << user_text << std::endl;
Ctrl+D
导致进程的 read
从终端立即到 return。如果您在键入 Hi my name is
后按 Ctrl+D
,该过程将读取:Hi my name is
。 getline
将找不到 \n
并将重新开始阅读。然后您再次按 Ctrl+D
(您没有说,但我确定您说了)。这将中断 read
,导致它变为 return 0,就好像终端已关闭一样。 getline
将 return 当前值:Hi my name is
.
在第二种情况下,自从上次\n
之后你没有输入任何内容,所以当你按Ctrl+D
时,read
直接returns 0和getline
returns 为空字符串。
std::getline
正在按预期工作:它正在排队。如果你按下回车键,它会创建一个新的空行;如果您随后按 ctrl+d,您将终止 std::getline,即 returns 该(空)行的内容。
来自docs:
getline reads characters from an input stream and places them into a string:
- Behaves as UnformattedInputFunction, except that input.gcount() is not affected. After constructing and checking the sentry object, performs the following:
- Calls str.erase()
- 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.
- If no characters were extracted for whatever reason (not even the discarded delimiter), getline sets failbit and returns.
- Same as getline(input, str, input.widen('\n')), that is, the default delimiter is the endline character.