2017-08-10 118 views
1

当我逐行读取文件时,我注意到了一些奇怪的行为。如果文件以\n(空行)结尾,则可能会跳过...但并非总是如此,我不明白是什么让它跳过或不跳过。std :: getline如何决定跳过最后一个空行?

我写了这个小功能,将字符串分割线重现轻松的问题:

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),我得到的输出:

(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" "" 

所以最后\n情况(6),(7)和(8)被忽略,罚款。但是,为什么不是(4)和(5)呢?

这种行为背后的理由是什么?

回答

1

有是quicky提到这个“奇怪”行为的一个有趣的帖子:getline() sets failbit and skips last line

由于menioned通过Rob's answer\n终止(这其实为什么它的名字线),而不是一个分隔符,这意味着行被定义为“以'\ n'”结尾,而不是由'\ n'“分隔”。

我不清楚这是如何回答这个问题的,但实际上它确实如此。如下重整,它变得清澈如水:

如果你的内容计算“\ n”,那么你会x线,或x+1最终的x OCCURENCES如果有一些额外的非“\ n”字符在文件的末尾。

(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)