Каков самый простой способ подсчета строк в ASCII файле?

Каков самый быстрый способ получить строки ASCII файла?

Ответы

Ответ 1

Обычно вы читаете файлы на C с помощью fgets. Вы также можете использовать scanf("%[^\n]"), но довольно многие люди, читающие этот код, скорее всего, найдут это запутанным и чужим.

Изменить: с другой стороны, если вы действительно хотите просто подсчитать строки, слегка измененная версия подхода scanf может работать довольно красиво:

while (EOF != (scanf("%*[^\n]"), scanf("%*c"))) 
    ++lines;

Преимущество этого заключается в том, что с '*' в каждом преобразовании scanf считывает и сопоставляет ввод, но ничего не делает с результатом. Это означает, что нам не нужно тратить память на большой буфер, чтобы удерживать содержимое строки, на которую мы не заботимся (и все еще можем получить строку, которая даже больше, чем это, поэтому наш счет заканчивается неправильно если мы не получим еще больше работы, чтобы выяснить, закончился ли ввод, который мы читаем, новой линией).

К сожалению, нам нужно разбить scanf на две части. scanf останавливает сканирование при неудачном преобразовании, и если вход содержит пустую строку (две последовательные строки новой строки), мы ожидаем, что первое преобразование завершится с ошибкой. Однако даже если это не удается, мы хотим, чтобы второе преобразование произошло, чтобы прочитать следующую новую строку и перейти к следующей строке. Поэтому мы пытаемся выполнить первое преобразование, чтобы "съесть" содержимое строки, а затем сделать преобразование %c для чтения новой строки (той части, которая нам действительно нужна). Мы продолжаем делать оба до тех пор, пока второй вызов scanf не вернет EOF (который обычно находится в конце файла, хотя он также может произойти в случае чего-то вроде ошибки чтения).

Edit2: Конечно, есть еще одна возможность, которая (по крайней мере, возможно) проще и понятнее:

int ch;

while (EOF != (ch=getchar()))
    if (ch=='\n')
        ++lines;

Единственная часть этого, которую некоторые люди считают противоречивой, заключается в том, что ch должен быть определен как int, а не char для правильного функционирования кода.

Ответ 2

Здесь решение на основе fgetc(), которое будет работать для строк любой длины и не требует выделения буфера.

#include <stdio.h>

int main()
{
    FILE                *fp = stdin;    /* or use fopen to open a file */
    int                 c;              /* Nb. int (not char) for the EOF */
    unsigned long       newline_count = 0;

        /* count the newline characters */
    while ( (c=fgetc(fp)) != EOF ) {
        if ( c == '\n' )
            newline_count++;
    }

    printf("%lu newline characters\n", newline_count);
    return 0;
}

Ответ 3

Может, мне что-то не хватает, но почему бы просто не сказать:

#include <stdio.h>
int main(void) {
  int n = 0;
  int c;
  while ((c = getchar()) != EOF) {
    if (c == '\n')
      ++n;
  }
  printf("%d\n", n);
}

если вы хотите подсчитать частичные строки (т.е. [^\n] EOF):

#include <stdio.h>
int main(void) {
  int n = 0;
  int pc = EOF;
  int c;
  while ((c = getchar()) != EOF) {
    if (c == '\n')
      ++n;
    pc = c;
  }
  if (pc != EOF && pc != '\n')
    ++n;
  printf("%d\n", n);
}

Ответ 4

Общий, почему вы сравниваете все символы? Это очень медленно. В файле размером 10 МБ это ~ 3 с.
При решении быстрее.

unsigned long count_lines_of_file(char *file_patch) {
    FILE *fp = fopen(file_patch, "r");
    unsigned long line_count = 0;

    if(fp == NULL){
        return 0;
    }
    while ( fgetline(fp) )
        line_count++;

    fclose(fp);
    return line_count;
}

Ответ 5

Как насчет этого?

#include <stdio.h>
#include <string.h>

#define BUFFER_SIZE 4096

int main(int argc, char** argv)
{
    int count;
    int bytes;
    FILE* f;
    char buffer[BUFFER_SIZE + 1];
    char* ptr;

    if (argc != 2 || !(f = fopen(argv[1], "r")))
    {
        return -1;
    }

    count = 0;
    while(!feof(f))
    {
        bytes = fread(buffer, sizeof(char), BUFFER_SIZE, f);
        if (bytes <= 0)
        {
            return -1;
        }

        buffer[bytes] = '\0';
        for (ptr = buffer; ptr; ptr = strchr(ptr, '\n'))
        {
            ++count;
            ++ptr;
        }
    }

    fclose(f);

    printf("%d\n", count - 1);

    return 0;
}