Какой самый простой способ подсчитать перевод строки в файле ASCII? - PullRequest
13 голосов
/ 25 ноября 2010

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

Ответы [ 5 ]

19 голосов
/ 25 ноября 2010

Обычно вы читаете файлы на 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 для правильной работы кода.

4 голосов
/ 25 ноября 2010

Вот решение, основанное на 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;
}
2 голосов
/ 12 марта 2013

Общее, почему Вы сравниваете все символы?Это очень медленно.В 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;
}
2 голосов
/ 25 ноября 2010

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

#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);
}
1 голос
/ 25 ноября 2010

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

#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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...