【发布时间】:2010-06-02 18:46:19
【问题描述】:
我正在使用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++ 将它们切断了。)这是一些奇怪的事情吗?以不同的方式喂养它?
编辑
显然,我需要在这里扩展一下。我遇到了两种确定文件中“行”是什么的哲学:
- 行由换行终止 - 在 Linux 等系统和 vim 等编辑器中占主导地位。由于没有最终的 '\n'(vim 中的“noeol”),可能会有一个稍微“奇怪”的文件。文件末尾不可能有空行。
- 行由换行分隔 - 在我遇到的几乎所有 Windows 编辑器中都占主导地位。每个文件都是有效的,最后一行可以为空。
当然,YMMV 关于换行符是什么。
我一直将它们视为两种完全不同的思想流派。我之前试图提出的一个观点是,询问 C++ 标准是明确还是隐含地遵循第一个标准。
因此,回到手头的问题,第二个例子,可以被认为是“A\nB\nC\n”有四行,遵循分离的哲学。现在,C++ 是否明确遵循终止的哲学,或者这只是标准的方式? (他们没有在标准中记录太多推理......)我不敢说它是明确的,因为判断你是否有 vim 所谓的 C++ 的“noeol”文件有点痛苦。 (例如,Python 会保留换行符,因此您可以这样判断)
由于 Windows 中的所有内容都遵循分离的理念,因此我正在寻找比“两个示例都有 3 行”更深入的内容。
(奇怪的是,Mac 在哪里终止或分离?)
【问题讨论】:
-
是的,这只是解释的问题。 C++ - 和许多其他语言 - 认为行是换行符终止的,而不是换行符分隔的。令人困惑的是,例如文本编辑器通常不会——但这就是生活。
-
从技术上讲,您没有空白的第四行。第三行仅以 '\n' 结尾,但第四行没有字符(因此没有第四行(无论您当前的文本编辑器告诉您什么))。在第四行添加一个空格,它将按预期工作。
标签: c++