std::getline()
来枚举文件中的行,它大多数情况下都可以正常工作。然而,我很好奇-如果文件最后一行为空,std::getline()
会跳过该行。以下是一个简单的示例:#include <iostream>
#include <string>
int main()
{
std::string line;
while(std::getline(std::cin, line))
std::cout << "Line: “" << line << "”\n";
return 0;
}
如果我将这个输入提供给它:
Line A
Line B
Line C
我看到那些代码返回了回来。但是这个:
Line A
Line B
Line C
[* line is present but blank, ie, the file end is: "...B\nLine C\n" *]
(很不幸,在SO的小代码框中我不能有空行...)所以,第一个文件有三行(["Line A","Line B","Line C"]),第二个文件有四行(["Line A","Line B","Line C",""])
对我来说,这似乎是错误的——我有一个四行的文件,并用getline()枚举它后只剩下了3行。让我真正困惑的是,这正是标准应该做的事情。(21.3.7.9)
即使Python也有类似的行为(但它也给了我换行符——C++则将其切掉了)。这是一种奇怪的情况,C++预期行以终止,而不是以'\n'分隔,而我却以不同的方式提供它?
编辑
显然,我需要再详细解释一下。我遇到过两种确定文件中“行”的哲学:
- 行以换行符终止——在Linux等系统和vim等编辑器中占主导地位。如果没有最后的'\n'(在vim中称为“noeol”),则可能会有一个略微“奇怪”的文件。无法在文件末尾有空行。
- 行由换行符分隔——在我遇到的几乎所有Windows编辑器中占主导地位。每个文件都是有效的,最后一行可以为空。
当然,换行符的定义可能因人而异。
我一直认为这两种方法是完全不同的思想。我之前提出的一个观点是询问C++标准是明确还是隐含地遵循第一种方法。
因此,回到手头的问题,第二个示例可以被视为“A\nB\nC\n”,按照分隔哲学有四行。现在,C++是否明确遵循了终止哲学,还是只是标准的方式?(他们在标准中没有记录太多的推理...)我不愿意说这是明确的,因为用C++很难告诉你是否有vim称为“noeol”的文件。(例如,Python保留了换行符,因此您可以以此方式确定)
由于Windows中的所有内容都遵循分隔哲学,因此我正在寻找比“两个示例都有3行”更深入的东西。
(奇怪的是,Mac在哪里?终止或分隔?)