How to count lines of a file in C++?

107,577

Solution 1

How about this :-

  std::ifstream inFile("file"); 
  std::count(std::istreambuf_iterator<char>(inFile), 
             std::istreambuf_iterator<char>(), '\n');

Solution 2

You read the file line by line. Count the number of lines you read.

Solution 3

This is the correct version of Craig W. Wright's answer:

int numLines = 0;
ifstream in("file.txt");
std::string unused;
while ( std::getline(in, unused) )
   ++numLines;

Solution 4

kernel methods following @Abhay

A complete code I've done :

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

it will not change the origin file stream state and including '\n'-miss situation processing for the last line.

Share:
107,577
malhobayyeb
Author by

malhobayyeb

Updated on December 12, 2021

Comments

  • malhobayyeb
    malhobayyeb over 2 years

    How can I count lines using the standard classes, fstream and ifstream?

  • James McNellis
    James McNellis almost 14 years
    That sounds like a huge overcomplication! ;-)
  • Billy ONeal
    Billy ONeal almost 14 years
    while ( ! in.eof() ) <--- NOOOOO! This will give garbage if there's any type of failure reading the file. Put std::getline as the condition of the while.
  • fingerprint211b
    fingerprint211b almost 14 years
    That's what I'd say, if you didn't say it before me. Still, your way is slightly better... +1
  • fingerprint211b
    fingerprint211b almost 14 years
    Just remembered something, What if the last line doesn't have a \n?
  • Abhay
    Abhay almost 14 years
    @fingerprint211b: Add one to the result :-) There is always this tradeoff whether u have a newline at the end of file.
  • Billy ONeal
    Billy ONeal almost 14 years
    @fingerprint211b: Then there is one less line. Just because the last line is blank does not mean it's any different than any other line.
  • Billy ONeal
    Billy ONeal almost 14 years
    It's still invalid after your edit because if std::getline fails, you increment the line count, and don't check if it succeeded until after. Move std::getline into the condition of the while.
  • wheaties
    wheaties almost 14 years
    Beautiful and elegant. Love that STL.
  • Abhay
    Abhay almost 14 years
    @wheaties: I also think think this is a faster way of counting lines in file if not the fastest. If you are reading lines, the system library (be it fgets or std::readline) will copy the data to your buffer; but an optimal solution will access the data in the buffer where it is read from the system, like memory mapping. So the truly optimal solution by the library could be to create a mmap_streambuf to mmap the file. A count_lines method would then just iterate over it there would never be a need to copy the data at all.
  • malhobayyeb
    malhobayyeb almost 14 years
    I cannot find "std:count" I just included <iostream>, <string> and <fstream>.
  • James McNellis
    James McNellis almost 14 years
    @MIH: A quick Google search would have told you that std::count() is in <algorithm>.
  • Abhay
    Abhay almost 14 years
    @MIH1406: #include <algorithm>
  • Cubbi
    Cubbi almost 14 years
    +1 for istream buf _iterator, as made famous by Item 29 of Effective STL!
  • Thomas Matthews
    Thomas Matthews almost 14 years
    How does one determine the average number of characters per line without reading the file? If your counting characters, you might as well just count the newlines instead; which kind of invalidates your answer.
  • synaptik
    synaptik over 11 years
    I get the error error: const struct std::basic_string<char, std::char_traits<char>, std::allocator<char> >' has no member named 'str' when I try to use this solution. Anyone know how to fix it?
  • Pietro
    Pietro about 11 years
    std::getline(in, std::string()) - Binding a non-const reference to a temporary is not legal C++.
  • qed
    qed over 10 years
    It looks like with std:ifstream you never have to close the file?
  • Abhay
    Abhay over 10 years
  • Parthian Shot
    Parthian Shot over 8 years
    Pretty sure this solution only works if you assume the encoding is low ASCII, since you're parameterizing the type with char, so you're comparing one octet at a time rather than one actual character at a time. That said, it works for my use case, so +1 to you. :)
  • DevSolar
    DevSolar about 8 years
    @ParthianShot: It will work for any of the ISO-8859 encodings, many Windows / DOS codepages, and UTF-8 as well (assuming the compiler encodes '\n' as 0x0a). By no means perfect, but sufficient if you can assert the file is in one of those encodings.
  • masoomyf
    masoomyf over 6 years
    return 1 for blank file or no file too.
  • 小文件
    小文件 over 6 years
    I think 0 may be better?
  • masoomyf
    masoomyf about 6 years
    yes 0 is required if there is nothing in file or file is not exists. But this function returns zero for blank file.
  • 小文件
    小文件 about 6 years
    if the blank file is a file with only blanks, the function can return 1 as expected~
  • David C. Rankin
    David C. Rankin about 5 years
    This method will give an invalid line count (1 too few lines) if the file lacks a POSIX eol (e.g. a '\n' at the end of the last line of text) And since there is no buffer to check whether it contains valid text, there is no way to catch that condition.
  • David C. Rankin
    David C. Rankin about 5 years
    Which is correct. Reading with a buffer is the only way to catch a non-POSIX eof.
  • Martin York
    Martin York about 5 years
    @DavidC.Rankin I would argue that the result is always one two small. The POSIX thing is a red hearing. If the last character is a new line then there is another line that is empty at the end. How does an empty line at the end differ from an empty line anywhere else in the file?
  • Remy Lebeau
    Remy Lebeau about 5 years
    A blank line is still a line, so the empty() check should be removed.
  • David C. Rankin
    David C. Rankin about 5 years
    The point is this size_t n = 0; while (getline (stream, string)) n++; will accurately report the number of lines regardless whether the file has a POSIX eof. The std::count approach, as shown in this answer, will fail to count the final line -- even though text is present to read. A line count should be accurate regardless. The underbelly to the whole issue the why a significant minority of text-editors continue to write files with non-POSIX endings. :)
  • Shudipta Sharma
    Shudipta Sharma over 4 years
    super solution !
  • Herwig
    Herwig about 3 years
    Awesome! This is exactly how 99.99% of the code I get from my predecessors is written!
  • Rick
    Rick almost 3 years
    @RemyLebeau depends on how you're defining lines, which the OP didn't specify.