Как подсчитать строки файла в C ++?

Как я могу подсчитать строки, используя стандартные классы fstream и ifstream?


person malhobayyeb    schedule 18.06.2010    source источник
comment
пахнет домашним заданием - что вы пробовали до сих пор?   -  person KevinDTimm    schedule 19.06.2010
comment
Начните с «1» и продолжайте добавлять 1 для каждой строки в файле.   -  person Edward Strange    schedule 19.06.2010
comment
@Noah: В пустом файле одна строка?   -  person Martin York    schedule 19.06.2010
comment
@Martin - Ты прав. ПОТЕРПЕТЬ ПОРАЖЕНИЕ.   -  person Edward Strange    schedule 19.06.2010
comment
Это должно быть обман, потому что я написал сообщение в блоге, основанное на другом разе, когда кто-то задал этот вопрос на Stack Overflow. adrianmccarthy.com/blog/?p=37   -  person Adrian McCarthy    schedule 19.06.2010
comment
Что означает line - учитывается ли содержимое между последним разрывом строки и концом файла? что, если бы сразу после перехода на строку следовало eof.   -  person Greg Domjan    schedule 19.06.2010


Ответы (7)


Как насчет этого :-

  std::ifstream inFile("file"); 
  std::count(std::istreambuf_iterator<char>(inFile), 
             std::istreambuf_iterator<char>(), '\n');
person Abhay    schedule 18.06.2010
comment
Я бы так сказал, если бы ты не сказал этого до меня. Тем не менее, ваш путь немного лучше ... +1 - person fingerprint211b; 19.06.2010
comment
Только что вспомнил, что, если в последней строке нет \ n? - person fingerprint211b; 19.06.2010
comment
@ fingerprint211b: Добавьте один к результату :-) Всегда есть компромисс, есть ли у вас новая строка в конце файла. - person Abhay; 19.06.2010
comment
@ fingerprint211b: Тогда на одну строчку меньше. То, что последняя строка пуста, не означает, что она отличается от любой другой строки. - person Billy ONeal; 19.06.2010
comment
Красиво и элегантно. Люблю этот STL. - person wheaties; 19.06.2010
comment
@wheaties: Я также думаю, что это более быстрый способ подсчета строк в файле, если не самый быстрый. Если вы читаете строки, системная библиотека (будь то fgets или std :: readline) скопирует данные в ваш буфер; но оптимальное решение будет обращаться к данным в буфере, откуда они считываются из системы, например, при отображении памяти. Таким образом, действительно оптимальным решением для библиотеки могло бы быть создание mmap_streambuf для mmap файла. Тогда метод count_lines просто перебирает его, и вообще никогда не будет необходимости копировать данные. - person Abhay; 19.06.2010
comment
Я не могу найти std: count. Я только что включил ‹iostream›, ‹string› и ‹fstream›. - person malhobayyeb; 19.06.2010
comment
@MIH: Быстрый поиск в Google сказал бы вам, что std::count() находится в <algorithm>. - person James McNellis; 19.06.2010
comment
@ MIH1406: #include <algorithm> - person Abhay; 19.06.2010
comment
+1 за istream buf _iterator, о чем свидетельствует пункт 29 действующего стандарта STL! - person Cubbi; 19.06.2010
comment
Когда я пытаюсь использовать это решение, я получаю сообщение об ошибке error: const struct std::basic_string<char, std::char_traits<char>, std::allocator<char> >' has no member named 'str'. Кто-нибудь знает, как это исправить? - person synaptik; 01.12.2012
comment
Похоже, что с std:ifstream вам не нужно закрывать файл? - person qed; 04.11.2013
comment
@qed: см. stackoverflow.com/questions/748014/ - person Abhay; 04.11.2013
comment
Совершенно уверен, что это решение работает только в том случае, если вы предполагаете, что кодировка имеет низкий ASCII, поскольку вы параметризуете тип с помощью char, поэтому вы сравниваете по одному октету за раз, а не по одному фактическому символу за раз. Тем не менее, это работает для моего варианта использования, поэтому +1 к вам. :) - person Parthian Shot; 04.11.2015
comment
@ParthianShot: он будет работать с любой из кодировок ISO-8859, многих кодовых страниц Windows / DOS, а также UTF-8 (при условии, что компилятор кодирует '\n' как 0x0a). Ни в коем случае не идеально, но достаточно, если вы можете утверждать, что файл находится в одной из этих кодировок. - person DevSolar; 21.04.2016
comment
Этот метод выдаст недопустимое количество строк (на 1 слишком мало строк), если в файле отсутствует POSIX eol (например, '\n' в конце последней строки текста). И поскольку нет буфера для проверки, содержит ли он действительный текст, там это не способ поймать это состояние. - person David C. Rankin; 15.03.2019
comment
@ DavidC.Rankin Я бы сказал, что результат всегда один два маленьких. POSIX - это красный слух. Если последний символ - это новая строка, то в конце остается еще одна пустая строка. Чем пустая строка в конце отличается от пустой строки где-либо еще в файле? - person Martin York; 15.03.2019
comment
Дело в том, что этот size_t n = 0; while (getline (stream, string)) n++; точно сообщит количество строк независимо от того, имеет ли файл POSIX eof. Подход std::count, как показано в этом ответе, не сможет подсчитать последнюю строку - даже если текст присутствует для чтения. В любом случае количество строк должно быть точным. Изюминкой всего вопроса является то, почему значительное меньшинство текстовых редакторов продолжают писать файлы с окончанием, отличным от POSIX. :) - person David C. Rankin; 15.03.2019
comment
супер решение! - person Shudipta Sharma; 08.01.2020

Вы читаете файл построчно. Подсчитайте количество прочитанных строк.

person Martin York    schedule 18.06.2010
comment
Звучит как огромное чрезмерное усложнение! ;-) - person James McNellis; 19.06.2010
comment
Что правильно. Чтение с буфером - единственный способ поймать не-POSIX eof. - person David C. Rankin; 15.03.2019

Это правильная версия ответа Крейга В. Райта:

int numLines = 0;
ifstream in("file.txt");
std::string unused;
while ( std::getline(in, unused) )
   ++numLines;
person Billy ONeal    schedule 18.06.2010
comment
std :: getline (in, std :: string ()) - Привязка неконстантной ссылки к временному объекту недопустима в C ++. - person Pietro; 08.04.2013

методы ядра после @Abhay

Полный код, который я сделал:

size_t count_line(istream &is)
{
    // skip when bad
    if( is.bad() ) return 0;  
    // save state
    std::istream::iostate state_backup = is.rdstate();
    // clear state
    is.clear();
    std::istream::streampos pos_backup = is.tellg();

    is.seekg(0);
    size_t line_cnt;
    size_t lf_cnt = std::count(std::istreambuf_iterator<char>(is), std::istreambuf_iterator<char>(), '\n');
    line_cnt = lf_cnt;
    // if the file is not end with '\n' , then line_cnt should plus 1  
    is.unget();
    if( is.get() != '\n' ) { ++line_cnt ; } 

    // recover state
    is.clear() ; // previous reading may set eofbit
    is.seekg(pos_backup);
    is.setstate(state_backup);

    return line_cnt;
}

он не изменит состояние потока исходного файла и не будет включать обработку ситуации «\ n» для последней строки.

person 小文件    schedule 08.06.2016
comment
вернуть 1 для пустого файла или без файла. - person masoomyf; 30.01.2018
comment
Думаю, 0 может быть лучше? - person 小文件; 30.01.2018
comment
да 0 требуется, если в файле ничего нет или файл не существует. Но эта функция возвращает ноль для пустого файла. - person masoomyf; 31.01.2018
comment
если blank file - это файл только с пробелами, функция может вернуть 1, как и ожидалось ~ - person 小文件; 01.02.2018


int numLines = 0;
ifstream in("file.txt");
//while ( ! in.eof() )
while ( in.good() )
{
   std::string line;
   std::getline(in, line);
   ++numLines;
}

Возникает вопрос, как вы относитесь к самой последней строке файла, если она не заканчивается новой строкой. В зависимости от того, что вы делаете, вы можете захотеть посчитать это, а можете нет. Этот код считает это.

См .: http://www.cplusplus.com/reference/string/getline/

person Craig Wright    schedule 18.06.2010
comment
while ( ! in.eof() ) ‹--- НЕЕЕТ! Это приведет к появлению мусора, если при чтении файла произойдет какой-либо сбой. Положите std::getline как условие на время. - person Billy ONeal; 19.06.2010
comment
Он по-прежнему недействителен после вашего редактирования, потому что, если std::getline не удается, вы увеличиваете счетчик строк и не проверяете, удалось ли это, до тех пор, пока не будет. Переведите std::getline в состояние пока. - person Billy ONeal; 19.06.2010

Разделите размер файла на среднее количество символов в строке!

person John    schedule 18.06.2010
comment
Как определить среднее количество символов в строке, не читая файл? Если вы подсчитываете символы, вы можете вместо этого просто подсчитать символы новой строки; что делает ваш ответ недействительным. - person Thomas Matthews; 19.06.2010
comment
Потрясающий! Именно так написано 99,99% кода, который я получил от своих предшественников! - person Herwig; 07.04.2021

person    schedule
comment
Пустая строка по-прежнему остается строкой, поэтому проверку empty() следует удалить. - person Remy Lebeau; 15.03.2019
comment
@RemyLebeau зависит от того, как вы определяете строки, которые OP не указал. - person Rick; 10.06.2021