Thread: Line Counting

  1. #1
    Registered User 00Sven's Avatar
    Join Date
    Feb 2006
    Posts
    127

    Line Counting

    I have been looking and determined that there is no C function that counts the number of lines in a file. I would like to make a function to do this but do not really know how. So far I have this
    Code:
    int linecount (FILE *file){
    	char ar[1024];
    	int count=0;
    	while(feof(file)==0){
    		fgets(ar,1024,file);
    		count++;
    	}
        return(count);
    }
    This for some reason always seems to return 0 though. Can someone please help with this. Thanks.
    ~Sven
    Windows XP Home Edition - Dev-C++ 4.9.9.2
    Quote Originally Posted by "The C Programming Language" by Brian W. Kernignhan and Dennis M. Ritchie
    int fflush(FILE *stream)
    On an output stream, fflush causes any buffered but unwritten data to be written; On an input stream, the effect is undefined. It returns EOF for a write error, and zero otherwise. fflush(NULL) flushes all output streams.
    board.theprogrammingsite.com

  2. #2
    Registered User
    Join Date
    Jan 2006
    Location
    Berkeley, Ca
    Posts
    195
    Maybe something like this

    input file

    line1
    line2
    line3
    line4

    Code:
    /*Count number of lines*/
    
    #include <stdio.h>
    #include <stdlib.h>
    
    #define BORED "/home/cdalten/cstuff/cstuff.txt"
    #define MAXLINE 400
    
    int linecount(FILE *fp) {
        char buff[MAXLINE];
        int count = 0;
    
        while(fgets(buff,MAXLINE,fp) != NULL) {
    	count++;
        }
        return count;
    }
    
    
    int main(int arg, char **argv) {
    
        FILE *fp;
    
        int value = 0;
    
        if ((fp=fopen(BORED,"r")) != NULL) {
    	  value = linecount(fp);
        }
    
        if(feof(fp)){
            printf("The value is: %d \n", value);
    	return 0;
        }
    
        if(ferror(fp)){
    	perror(argv[0]);
    	return -1;
        }
    
        fclose(fp);
        return 0;
    }
    
    $gcc -Wall lc.c -o lc
    $./lc
    The value is: 4
    $
    Last edited by Salem; 04-01-2006 at 12:28 AM. Reason: Replace "colourful" example text with something neutral

  3. #3
    Registered User
    Join Date
    Mar 2006
    Location
    Bangalore, INDIA
    Posts
    43
    Hey, I think u can go for one more way of doing it by searching for "\n" and increase the count by one whenever u find "\n". This may work fine

  4. #4
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,164
    Quote Originally Posted by 00Sven
    I have been looking and determined that there is no C function that counts the number of lines in a file. I would like to make a function to do this but do not really know how. So far I have this
    Code:
    int linecount (FILE *file){
    	char ar[1024];
    	int count=0;
    	while(feof(file)==0){
    		fgets(ar,1024,file);
    		count++;
    	}
        return(count);
    }
    This for some reason always seems to return 0 though. Can someone please help with this. Thanks.
    ~Sven
    Your concept is fine, with a couple small problems.

    Problem #1 is your use of feof(). See this FAQ for an explanation.

    Next, what if a line is 1123 characters? fgets() will read the first 1023 and the next fgets() will read the last 100 characters. Test the last character in your buffer (using strlen()) for the \n and increase the count only if it's there.
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

  5. #5
    Registered User
    Join Date
    Jan 2006
    Location
    Berkeley, Ca
    Posts
    195
    Quote Originally Posted by WaltP
    Your concept is fine, with a couple small problems.

    Problem #1 is your use of feof(). See this FAQ for an explanation.

    Next, what if a line is 1123 characters? fgets() will read the first 1023 and the next fgets() will read the last 100 characters. Test the last character in your buffer (using strlen()) for the \n and increase the count only if it's there.
    I haven't test this, but wouldn't something like this also work

    Code:
    int linecount = 0; 
    int lastchar = '\n'; 
    
    while (fgets(buffer, MAXLINE, fp)) 
             if (strchr(buffer, lastchar)) 
                 ++count; 
     
        if (ferror(fp)) { 
             fprintf(stderr, "Error reading the input file\n"); 
             exit(EXIT_FAILURE); 
         } 
     
       if (!strchr(buffer, lastchar)) 
             ++count;

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Why do you have two strchr() calls?
    What does the last one do for you?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Jan 2006
    Location
    Berkeley, Ca
    Posts
    195
    It was the first thing that came to my snoodle when I thought about treating any trailing characters without a new-line as a line.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    True, but you also have to contend with a file which may be empty as well.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Jan 2006
    Location
    Berkeley, Ca
    Posts
    195
    Code:
    while (fgets(buffer, MAXLINE, fp))
    is the same as
    Code:
    while (fgets(buffer, MAXLINE, fp) != NULL)
    If the file exists and there is nothing in the file, the code should fail. Right? Again, I didn't test this.

  10. #10
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Yes, fgets() returns NULL if no characters were stored in the string before EOF was encountered.

    This code:
    Code:
    while(fgets(line, sizeof(line), fp)) count ++;
    is better than just counting newlines, because you can have a line in a file that isn't terminated by a newline. That is, if you have a file with the contents "foo", the fgets() method will claim the file has one line (which is probably what you want), whereas just counting the newlines would give you zero lines.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  11. #11
    Sys.os_type="Unix";;
    Join Date
    Aug 2005
    Posts
    52
    Quote Originally Posted by dwks
    Yes, fgets() returns NULL if no characters were stored in the string before EOF was encountered.

    This code:
    Code:
    while(fgets(line, sizeof(line), fp)) count ++;
    is better than just counting newlines, because you can have a line in a file that isn't terminated by a newline. That is, if you have a file with the contents "foo", the fgets() method will claim the file has one line (which is probably what you want), whereas just counting the newlines would give you zero lines.
    True but what happens if the line exceeds the array limits? It would continue to pull in data until it reached the new-line character each time doing a call to fgets and incrementing the counter each time as well?

  12. #12
    Registered User
    Join Date
    Jan 2006
    Location
    Berkeley, Ca
    Posts
    195
    Hmm....I never thought about using sizeof(). Hahaha. Inexperience rears its ugly head huh?

  13. #13
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Well this is tough because we can't just check for like;

    Code:
    if(line[strlen(line) - 1] == '\n')
    {
    	count++;
    }
    Because of the aforementioned single line then EOF thing. Is there any sort of straight-forward solution? Is fgets a bad way to do this maybe?

  14. #14
    Registered User
    Join Date
    Jul 2003
    Posts
    110
    ...Because of the aforementioned single line then EOF thing. Is there any sort of straight-forward solution? Is fgets a bad way to do this maybe?
    I don't see a compelling reason to use fgets here. After all, all versions posted so far simply discard the input. Using [f]scanf to discard the characters might yield a nicer solution.

    The call scanf("%*[^\n]"); means "read all characters up to but *not* including the newline character and discard them". The '*' in this case means assignment suppression. A following call to getchar() removes the '\n' if it was there, otherwise it simply does nothing and evaluates to EOF.

    Any solution should handle:
    1) Empty files
    2) Files with blank lines
    3) Files with ill-formed last lines (no newline character before EOF)
    4) Well formed last lines (newline character appears before EOF)

    Perhaps even more, but I can't think of any off the top of my head.

    HTH,
    Will

  15. #15
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,164
    fgets() is the way to do this. After you read a line:
    1) if the end of the text read ends with \n, count it. You read a line.
    2) if the end of the text read does not end with \n, don't count it. You read the start but not the end of the line. The input buffer will be full in this case.
    3) if you get EOF, you have reached the end of the file, exit the read loop. The input buffer still has the previous line read. Now test the end character again. If it does not contain a \n, count it. It's the last line.
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Imposing Line Numbers automatically in the C code
    By cavestine in forum C Programming
    Replies: 14
    Last Post: 10-15-2007, 12:41 AM
  2. Adding Line numbers in Word
    By Mister C in forum A Brief History of Cprogramming.com
    Replies: 24
    Last Post: 06-24-2004, 08:45 PM
  3. Trouble replacing line of file
    By Rpog in forum C Programming
    Replies: 4
    Last Post: 04-19-2004, 10:22 AM
  4. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM
  5. follow up with char I/O and line, word, and char counting
    By Led Zeppelin in forum C Programming
    Replies: 1
    Last Post: 03-23-2002, 09:26 PM