2017-08-10 117 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)