2017-08-10 4 views
1

J'ai remarqué un comportement étrange lors de la lecture d'un fichier par ligne. Si le fichier se termine par \n (ligne vide), il peut être ignoré ... mais pas toujours, et je ne vois pas ce qui le fait sauter ou non.Comment std :: getline décide-t-il d'ignorer la dernière ligne vide?

j'ai écrit cette petite division de la fonction d'une chaîne en lignes pour reproduire le problème facilement:

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; 
} 

Quand je le tester (http://cpp.sh/72dgw), je reçois ces sorties:

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

donc dernier \n est sauté pour le cas (6), (7) et (8), très bien. Mais pourquoi ce n'est pas pour (4) et (5) alors?

Quelle est la raison derrière ce comportement?

Répondre

1

Il y a un poste intéressant que mentionné Quicky ce comportement « étrange »: getline() sets failbit and skips last line

Comme menioned par Rob's answer, \n est une terminaison (qui est en fait pourquoi il est des noms Fin de ligne), pas séparateur, ce qui signifie que les lignes sont définies comme "se terminant par un '\ n'" et non comme étant "séparées par un '\ n'".

Je ne comprenais pas comment cela répondait à la question, mais c'est effectivement le cas. Reformulant comme ci-dessous, il devient clair que l'eau:

Si votre contenu compte x occurences de « \ n », alors vous vous retrouverez avec x lignes ou x+1 s'il y a des fonctionnalités supplémentaires non « \ n » caractères à la fin du fichier.

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