std :: getline如何决定跳过最后一个空行? [英] How does std::getline decides to skip last empty line?
问题描述
按行读取文件时,我注意到一些奇怪的行为.如果文件以\n
(空行)结尾,则可能会被跳过...但并非总是如此,而且我看不出是什么使它被跳过了.
I noticed some strange behaviour when reading a file by line. If the file ends with \n
(empty line), it may be skipped...but not always, and I don't see what makes it be skipped or not.
我编写了这个小函数,将字符串分成几行以轻松重现该问题:
I wrote this little function splitting a string into lines to reproduce the issue easily:
std::vector<std::string> SplitLines( const std::string& inputStr )
{
std::vector<std::string> lines;
std::stringstream str;
str << inputStr;
std::string sContent;
while ( std::getline( str, sContent ) )
{
lines.push_back( sContent );
}
return lines;
}
当我对其进行测试( http://cpp.sh/72dgw )时,我得到了以下输出:
When I test it (http://cpp.sh/72dgw), I get those outputs:
(1) "a\nb" was splitted to 2 line(s):"a" "b"
(2) "a" was splitted to 1 line(s):"a"
(3) "" was splitted to 0 line(s):
(4) "\n" was splitted to 1 line(s):""
(5) "\n\n" was splitted to 2 line(s):"" ""
(6) "\nb\n" was splitted to 2 line(s):"" "b"
(7) "a\nb\n" was splitted to 2 line(s):"a" "b"
(8) "a\nb\n\n" was splitted to 3 line(s):"a" "b" ""
因此对于情况(6),(7)和(8)可以跳过最后一个\n
.但是为什么不适合(4)和(5)呢?
So last \n
is skipped for case (6), (7) and (8), fine. But why it's not for (4) and (5) then?
这种行为背后的原因是什么?
What's the rational behind this behaviour?
推荐答案
There is an interesting post that quicky mentioned this "strange" behaviour: getline() sets failbit and skips last line
Rob的答案中提到,\n
是终结符(这就是为什么它的名称是 End Of Line),而不是分隔符,这意味着行被定义为以'\ n'结尾",而不是被"\'分隔n'".
As menioned by Rob's answer, \n
is a terminator (that's actually why it's names End Of Line), not a separator, meaning that lines are defined as "ending by a '\n'", not as being "separated by a '\n'".
我不清楚这如何回答问题,但实际上确实如此.重新配制如下,变得清澈如水:
It was unclear to me how this answered the question, but it actually does. Reformulating as below, it becomes clear as water:
如果您的内容计数为x
出现的'\ n',那么您将以x
行结尾,或者如果结尾处还有一些额外的非'\ n'字符,则返回x+1
文件.
If your content counts x
occurences of '\n', then you'll end up with x
lines, or x+1
if there is some extra non '\n' characters at the end of the file.
(1) "a\nb" splitted to 2 line(s):"a" "b" (1 EOL + extra characters = 2 lines)
(2) "a" splitted to 1 line(s):"a" (0 EOL + extra characters = 1 line)
(3) "" splitted to 0 line(s): (0 EOL + no extra characters = 0 line)
(4) "\n" splitted to 1 line(s):"" (1 EOL + no extra characters = 1 line)
(5) "\n\n" splitted to 2 line(s):"" "" (2 EOL + no extra characters = 2 lines)
(6) "\nb\n" splitted to 2 line(s):"" "b" (2 EOL + no extra characters = 2 lines)
(7) "a\nb\n" splitted to 2 line(s):"a" "b" (2 EOL + no extra characters = 2 lines)
(8) "a\nb\n\n" splitted to 3 line(s):"a" "b" "" (3 EOL + no extra characters = 3 lines)
这篇关于std :: getline如何决定跳过最后一个空行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!