std :: getline如何决定跳过最后一个空行? [英] How does std::getline decides to skip last empty line?

查看:201
本文介绍了std :: getline如何决定跳过最后一个空行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

按行读取文件时,我注意到一些奇怪的行为.如果文件以\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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆