Единственная проблема, которая может повлиять на количество возвращаемых строк независимо от используемого вами метода, заключается в том, содержит ли файл POSIX-совместимый код '\n'
в конце последней строки.Существует ряд редакторов (и программ), которые с радостью записывают окончательный объем текста в файл без конца строки POSIX.Вы можете обрабатывать любой случай независимо от того, какой метод вы используете для определения количества строк в файле.
Если вы пытаетесь определить количество строк в большом файле, то вам определенно нужно буферизованное чтение (например, чтение нескольких символов в буфер, для чтения), а не посимвольный подход.Это может значительно повысить эффективность.
Соединяя эти две части, вы можете использовать либо fgets
, либо POSIX getline
, чтобы довольно эффективно определить количество строк в файле.Например, с getline
(который обрабатывает проблему конца строки или с вами), вы можете сделать:
/** 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;
}
С fgets
, тестирование на дополнительный текст после окончательного новой строки зависит от вас, например,
/** 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;
}
( примечание: вы можете добавить свой собственный код для обработки fopen
сбоя в каждой функции.)