[英]getline() sets failbit and skips last line
我正在使用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在哪里终止或分开?)
C ++标准对getline
有这样的说法:
C ++ 2003,21.3.7.9 / 5
[
getline(is, str, delim)
]…从is
…中提取字符,直到发生以下任何一种情况:
- 文件结束出现在输入序列上……
c == delim
[ Nb默认delim为'\\n'
]用于下一个可用的输入字符c
(在这种情况下,c被提取但未附加)- 存储
str.max_size()
字符
添加了方括号内的编辑评论
要将它放在您的母语中, getline
会将'\\n'
视为终止符,而不是分隔符。
在您的两个数据集中,我只计算三行。 第一个数据集只是缺少第二个数据集中存在的行尾字符。
为了方便起见,您的编辑器在“ C行”之后代表一个空行。 如果通过wc -l用管道传输内容,则会发现它显示3。
当您说最后一行是空白时,您是什么意思? 如果您的意思是倒数第二行以回车/换行符结尾,那么从技术上讲您没有最后一行,这听起来像是getline()的行为符合我的预期。
考虑您的示例:
Line A
Line B
Line C
这实际上是三行以\\ r \\ n结尾,第三行的\\ r \\ n是将光标置于第四行的原因。 实际上没有第四行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.