我正在使用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的小代码框中没有空行......) 因此,第一个文件有三行([“行A”,“行B”,“行C”]),第二个文件有四行([“行A”,“行B”,“行C”,“”] )
这对我来说似乎不对 - 我有一个四行文件,并用getline()枚举它让我留下3.真正让我摸不着头脑的是,这正是标准所说应该做的。 (21.3.7.9)
即使Python也有类似的行为(但它也给了我新行--C ++将它们删除了。)这是一个奇怪的事情,C ++预期行被终止,而不是由'\ n'分隔,我是以不同的方式喂养它?
显然,我需要在这里扩展一下。我已经遇到了两种确定文件中“行”的哲学:
当然,YMMV关于新行是什么。
我一直认为这是两种完全不同的思想流派。我试图提出的一个更早的观点是询问C ++标准是否明确地或仅仅隐含地跟随第一个。
因此,回到手头的问题,第二个例子,可以被认为是“A \ nB \ nC \ n”,它有四个行,遵循分离的哲学。现在,C ++是否明确遵循终止的哲学,或者这只是标准的方式? (他们没有在标准中记录太多推理......)我很犹豫地说这是明确的,因为告诉你是否有什么vim用C ++调用“noeol”文件有点痛苦。 (例如,Python留下了换行符,所以你可以这样说)
由于Windows中的所有内容都遵循分离的哲学,我正在寻找比“两个示例都有3行”更深刻的东西。
(奇怪的是,Mac在哪里?终止或分开?)
答案 0 :(得分:3)
C ++标准可以说getline
:
C ++ 2003,21.3.7.9 / 5
[
getline(is, str, delim)
] ...从is
中提取字符...直到出现以下任何一种情况:
- 文件结尾出现在输入序列...
c == delim
[ N.b.对于下一个可用输入字符'\n'
,默认分隔为c
](在这种情况下,c被提取但未被追加)str.max_size()
个字符存储
Bracketd编辑评论补充
用你的白话来说,getline
将'\n'
视为终结者,而不是分隔符。
答案 1 :(得分:1)
我的数据集中只计算了三行。第一个数据集只是缺少第二个数据集中出现的行结束字符。
为方便起见,您的编辑器在'C行'后面代表一个空行。如果你通过wc -l管道它的内容,你会发现它说3。
答案 2 :(得分:0)
当你说最后一行是空白的时候是什么意思?如果你的意思是倒数第二行以回车符/换行符结束,那么你在技术上没有最后一行,听起来像getline()的表现就像我期望的那样。
考虑你的例子:
Line A
Line B
Line C
这实际上是以\ r \ n结尾的三行,而第三行的\ r \ n是将光标放在第4行的行。实际上并没有第4行。