Как std :: getline решает пропустить последнюю пустую строку?

Я заметил странное поведение при чтении файла построчно. Если файл заканчивается \n (пустая строка), это может быть пропущено … но не всегда, и я не вижу, что делает это пропущенным или нет.

Я написал эту маленькую функцию, разбивающую строку на строки, чтобы легко воспроизвести проблему:

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

Что является рациональным за этим поведением?

2

Решение

Есть интересный пост, в котором быстро упоминается это «странное» поведение: getline () устанавливает failbit и пропускает последнюю строку

Как упомянуто Ответ Роба, \n это терминатор (это на самом деле, почему это имена Конец Линии), а не разделитель, это означает, что строки определены как «заканчивающиеся символом« \ n »», а не как «разделенные символом« \ n ».

Мне было неясно, как это ответило на вопрос, но это действительно так. Переформулировав, как показано ниже, оно становится прозрачным, как вода:

Если ваш контент имеет значение x в случае ‘\ n’, вы получите x линии или x+1 если в конце файла есть дополнительные не \ 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)
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]