Count number of line using C

后端 未结 5 1381
无人共我
无人共我 2020-12-16 07:58

Is there a way to count the number of lines in my file using C?

5条回答
  •  自闭症患者
    2020-12-16 08:26

    One nagging issue that can effect the number of lines returned regardless of the method you use is whether the file contains a POSIX compliant '\n' at the end of the last line. There are a number of editors (and programs) that happily write the final amount of text to a file without the POSIX end-of-line. You can handle either case regardless of which method you use to determine the number of lines in a file.

    If you are trying to determine the number of line in a large file, then you will definitely want a buffered read (e.g. reading multiple characters into a buffer, per-read) rather than a character-by-character approach. The can greatly improve the efficiency.

    Putting those two pieces together, you can use either fgets or POSIX getline to determine the number of lines in a file fairly efficiently. For example with getline (which handles the line-end issue or you), you could do:

    /** open and read each line in 'fn' returning the number of lines */
    size_t nlinesgl (char *fn)
    {
        if (!fn) return 0;
    
        size_t lines = 0, n = 0;
        char *buf = NULL;
        FILE *fp = fopen (fn, "r");
    
        if (!fp) return 0;
    
        while (getline (&buf, &n, fp) != -1) lines++;
    
        fclose (fp);
        free (buf);
    
        return lines;
    }
    

    With fgets, testing for additional text after the final newline is up to you, e.g.

    /** note; when reading with fgets, you must allow multiple reads until
     *  '\n' is encountered, but you must protect against a non-POSIX line
     *  end with no '\n' or your count will be short by 1-line. the 'noeol'
     *  flag accounts for text without a '\n' as the last line in the file.
     */
    size_t nlines (char *fn)
    {
        if (!fn) return 0;
    
        size_t n = 0, noeol = 0;
        char buf[FILENAME_MAX] = "";
        FILE *fp = fopen (fn, "r");
    
        if (!fp) return 0;
    
        while (fgets (buf, FILENAME_MAX, fp)) {
            noeol = 0;
            if (!strchr (buf, '\n')) {
                noeol = 1;  /* noeol flag for last line */
                continue;
            }
            n++;
        }
        if (noeol) n++;     /* check if noeol, add 1 */
    
        fclose (fp);
    
        return n;
    }
    

    (note: you can add your own code to handle a fopen failure in each function.)

提交回复
热议问题