Как посчитать количество строк в файле в C? - PullRequest
1 голос
/ 05 июня 2019

У меня есть функция, которая должна подсчитывать количество строк в файле, введенном пользователем.Однако всякий раз, когда я вводю файл, моя функция продолжает возвращать 0 строк.

int findnum_lines(FILE* fp){

  int num_lines = 0;
  char line;
  int size;

  size = ftell(fp);
  line = getc(fp);
  if(size != 0){
    while(line != EOF){
      if(line == '\n'){
        num_lines = num_lines + 1;
      }
      line = getc(fp);
    }
  } else {
    num_lines = 0;
  }
  printf("%d", num_lines);
  return num_lines;
}

int main(int argc, char* argv[]){
    char** lines = NULL;
    int num_lines = 0;
    FILE* fp = validate_input(argc, argv);

    num_lines = findnum_lines(fp);
    read_lines(fp, &lines, &num_lines);
    print_lines(lines, num_lines);
    free_lines(lines, num_lines);
    fclose(fp);

    return 0;
}

Мой пример файла:

Hello Class
This is what I would call a normal file
It isn't very special
But it still is important

Таким образом, моя функция должна возвращать 4 строки, а не 0.

ОБНОВЛЕНО:

int findnum_lines(FILE* fp){

  int num_lines = 0;
  int line;

  line = getc(fp);

  while(line != EOF){
    if(line == '\n'){
      num_lines = num_lines + 1;
      }
    line = getc(fp);
    }
  printf("%d", num_lines);
  return num_lines;
}

int main(int argc, char* argv[]){
    char** lines = NULL;
    int num_lines = 0;
    FILE* fp = validate_input(argc, argv);

    num_lines = findnum_lines(fp);
    read_lines(fp, &lines, &num_lines);
    print_lines(lines, num_lines);
    free_lines(lines, num_lines);
    fclose(fp);

    return 0;
}

С этим обновленным кодом не печатается num_lines.

Ответы [ 2 ]

4 голосов
/ 05 июня 2019

ftell сообщает текущую позицию в файле. Для файла, который был только что открыт, позиция является началом, а ftell возвращает ноль. Затем, поскольку size равно нулю, цикл в findnum_lines обрабатывает ноль символов и сообщает, что строки не найдены.

Как правило, вы не хотите получать размер файла, а затем зацикливаться на этом. Одна из причин заключается в том, что файл может измениться, пока вы его читаете - другие процессы могут записать в него больше данных или усечь его. Другая причина в том, что это не нужно. Просто читайте символы, пока не получите EOF, используя цикл while (или цикл do … while).

Кроме того, char line; должно быть int line;, поскольку оно используется для хранения результата getc, который может быть либо символом, либо EOF, а char недостаточно для хранения EOF. (Кроме того, getc возвращает значение символа как unsigned char, преобразованное в int, поэтому в реализации, где подписано char, char не может даже правильно представить все символы.)

2 голосов
/ 05 июня 2019

Одной из проблем является то, что вызов ftell() выполняется со смещением файла, равным нулю:

int findnum_lines(FILE* fp){

  int num_lines = 0;
  int line; // changed char to int
  int size;

  size = ftell(fp);
  line = getc(fp);
  if(size != 0){
    while(line != EOF){
      if(line == '\n'){
        num_lines = num_lines + 1;
      }
      line = getc(fp);
    }
  } else {
    num_lines = 0;
  }
  printf("%d", num_lines);
  return num_lines;
}

Если findnum_lines() вызывается сразу после открытия файла, текущее смещение файла, возвращаемое ftell(), будет в начале файла - или ноль.

Итак, num_lines устанавливается в ноль, и возвращается ноль.

Обратите внимание, что проверка размера файла не требуется - поскольку вы подсчитываете символы новой строки - '\n' - файл нулевой длины будет содержать ноль символов новой строки для подсчета.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...