Is there a way to count the number of lines in my file using C?
Try the wc
command. Most linux distributions include it.
If you are referring to the line number within your c source, most compilers support the __LINE__
macro.
If you want to count line numbers of arbitrary text files in c, the following functions should be starting points:
Combining these into a line counter is left as an exercise to the reader :)
Please think for a moment about what you have to do to count lines in a file:
Open the file for reading, maybe with fopen( );
Read each line, one line at a time, maybe with fread( );
Increment a line counter that you've initialized to zero earlier;
Whwn end-of-file is returned from the next read of the file, you are done. printf( ) the line counter.
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.)
If you want to perform this programmatically, open the file in text mode and perform fgetc() operation until you reach end of file. Keep a count of number of times fgetc was called.
FILE *fp = fopen("myfile.txt");
int ch;
int count=0;
do
{
ch = fgetc(fp);
if(ch == '\n') count++;
} while( ch != EOF );
printf("Total number of lines %d\n",count);