为什么我需要 std::endl 来重现我用 getline() 得到的输入行?

Why do I need std::endl to reproduce input lines I got with getline()?

提问人:Sean Lau 提问时间:8/14/2022 最后编辑:einpoklumSean Lau 更新时间:8/14/2022 访问量:128

问:

我是一个新手,正在学习C++来读取或写入文件。我搜索了如何从文件中读取所有内容,并得到了可以使用while循环的答案。

string fileName = "data.txt";
string line ;
ifstream myFile ;
myFile.open(fileName);
while(getline(myFile,line)){
    cout << line << endl;
}

data.txt 有三行内容和输出,如下所示。

Line 1
Line 2
Line 3

但是,如果我删除并仅在 while 循环的大括号中使用,则输出将更改为:"endl"cout<<line;

 Line 1Line 2Line 3

据我了解,while 循环执行了 3 次,背后的逻辑是什么?

C++ C++11 IOstream 获取线

评论

1赞 n. m. could be an AI 8/14/2022
向你的橡皮鸭解释一下这是做什么的。当您删除它时,这将是它停止做的事情。endl
2赞 Bob__ 8/14/2022
你是在问为什么不包括换行符吗?这就是 std::getline 的工作方式。line
2赞 einpoklum 8/14/2022
这实际上是一个有趣的问题,因为 C 的 getline 在结果中保留了换行符
2赞 phuclv 8/14/2022
在大多数情况下也是一个坏主意。只需使用std::endlstd::cout << '\n'

答:

2赞 John Zwinck 8/14/2022 #1

endl意思是“终点线”,它做两件事:

  1. 将输出光标移动到下一行。
  2. 刷新输出,以防您写入文件,这意味着该文件将立即更新。

通过删除,您将所有输入行写入单个输出行,因为您从未被告知要转到下一行。endlcout

评论

0赞 Sean Lau 8/14/2022
嗨,约翰,谢谢你的回答,但这不是我要问的,我对为什么循环被执行 3 次以及 getline() 函数在此代码中的工作方式感到困惑。我的理解是,当getline()到达文件末尾时,它将返回false。
0赞 John Zwinck 8/14/2022
好的,如果你的文件有 3 行,并且你明白 getline 一次只得到一行,你希望循环迭代多少次?
0赞 Sean Lau 8/14/2022
是的,我想确认 getline 是否一次获取一行,并将 true 返回到 while 循环。在到达最后一行并返回 true 之前,如果文件结束,getline 将返回 false。因此,循环结束。
0赞 einpoklum 8/14/2022
但是为什么不保留换行符/换行符呢?它在 C 中这样做。std::getline()
1赞 John Zwinck 8/14/2022
std::getline()仅当没有剩余输入时才返回 false。这意味着它被调用了四次:前三次有可用的数据,它返回 true 到 while 循环。最后一次返回 false,因为输入已耗尽,因此循环结束。
1赞 einpoklum 8/14/2022 #2

您的问题涉及语义歧义:它的结果应该是“一行”,在这种情况下,结果应该包括行尾换行符,或者结果应该是一行的内容,在这种情况下,尾随换行符应该被删除?std::getline()

在 C 编程语言中,getline() 采用第一种方法:

getline() 从流中读取整行...[result] 缓冲区是 null-terminated,并包含换行符(如果找到)。

但在 C++ 中,语义是不同的:换行符被认为是分隔符,重复调用的结果是没有分隔符的内容。请注意,该函数实际上在第三个参数中采用分隔符,该参数默认为 ,但可以替换为任何其他单个字符。这使得更多的是分词器std::getline()'\n'std::getline()