Подсчет количества строк в файле .txt в c - PullRequest
0 голосов
/ 28 мая 2020

У меня есть файл process.txt, который содержит подробную информацию о входящих процессах, например,

0 4 96 30
3 2 32 40
5 1 100 20
20 3 4 30

Я хотел найти количество строк в этом файле. Как это можно сделать?

Я пробовал этот код, но он всегда возвращает количество строк как 0

char c;
int count = 0;
// fp is the pile pointer
for (c = getc(fp); c != EOF; c = getc(fp)) 
        if (c == '\n') // Increment count if this character is newline 
            count = count + 1; 

Ответы [ 3 ]

1 голос
/ 28 мая 2020

Помимо char, который должен быть int, ваш код более или менее хорош. Проблема находится где-то в коде, который вы не показывали.

Это работает:

#include <stdio.h>

int main() {
  FILE* fp = fopen("processes.txt", "r");
  if (fp == NULL)
  {
    printf("Could not open file.");
    return 1;
  }

  int c;    // this must be an int
  int count = 0;

  for (c = getc(fp); c != EOF; c = getc(fp))
    if (c == '\n') // Increment count if this character is newline 
      count = count + 1;

  printf("The file has %d line(s)\n", count);

  fclose(fp);
}

Однако, если последняя строка файла не заканчивается на \n, это не учитывается.

1 голос
/ 29 мая 2020

Прочтите, пожалуйста, Как создать минимальный, полный и проверяемый пример .

Чтобы протестировать фрагмент вашей программы, мне сначала нужно было завершить ваш фрагмент кода, чтобы это компилируемый. Вероятно, ваша ошибка исчезла с этими изменениями, поскольку мой запуск показывает (над вашим входным текстом) этот вывод:

pru. c

#include <stdio.h>

int main()
{
        char c;
        int count = 0;
        FILE *fp = stdin; // most probably your error is
                          // related to this initialization.

        // fp is the pile pointer
        for (c = getc(fp); c != EOF; c = getc(fp)) 
                        if (c == '\n') // Increment count if this character is newline 
                                count = count + 1;
        printf("%d\n", count);

        return 0;
}

и запускает его:

$ pru <<EOF
0 4 96 30
3 2 32 40
5 1 100 20
20 3 4 30
EOF
4
$ _

Какой ответ правильный.

Несмотря на это, фрагмент вашей программы показывает невидимую ошибку , как вам было сказано в комментариях к вашему вопросу : тип c переменной должен быть int, а не char, но почему?

Поскольку char - это тип, который вы хотите получить, возможны все доступные значения, поэтому, чтобы указать, что в вашем файле обнаружено какое-то особое условие (конец данных в потоке или EOF не одно из этих значений, а особое условие) требуется одно дополнительное значение , поэтому тип char недостаточен для включения всех возможных возвращаемых значений из fgetc(3). Это причина, по которой функция fgetc(3) должна возвращать int.

Проверьте документацию fgetc(3), так как ваша программа работает почти нормально, но вам нужно указать причину, почему:

Когда программа считывает символ, он преобразуется в int значения 0 в 255, поэтому все разные байты преобразуются как положительные целочисленные значения, тогда как обычно (почти каждая реализация) EOF - отображается в целочисленное значение -1. Здесь происходит то, что все ваши значения преобразуются в char, в результате чего EOF отображается в одно из этих 0 в 256 значений (которое зависит от реализации , но обычно это значение 255 --- или -1, если char оказывается подписанным), поэтому:

  • в случае, если ваш тип char представлен как дополнение до двух введите (signed) ваши значения от 0 до 255 отображаются в 0 на 127 и -128 на -1, а значение EOF сопоставляется с некоторыми из них (в основном -1).
  • в случае, если ваш тип char представлен как тип без знака, ваши значения от 0 до 255 отображаются в 0 на 255, а значение EOF отображается к одному из них (наиболее вероятно 255)
  • , не имеет значения, в какое значение преобразуется EOF, поскольку вы проводите сравнение в системе согласованных типов, поэтому преобразовано * Значение 1077 * char сравнивается со значением преобразовано EOF, в результате чего EOF преобразуется в преобразованное значение EOF. Но это заставляет другое значение char показывать такое же поведение, что заставляет один такой символ на входе интерпретироваться как EOF и заставляет вашу программу преждевременно останавливаться.

In в обоих случаях, описанных выше, если введен байт с таким же сопоставленным с значением EOF, ваша программа завершит sh, полагая, что она достигла конца файла, и ваш счет будет быть ошибочным. Здесь дело обстоит не так, но вы можете получить сюрприз, обнаружив один файл с таким символом.

Итак, ваша окончательная программа (исправленная) будет:

#include <stdio.h>

int main()
{
        int c;
        int count = 0;
        FILE *fp = stdin;

        // fp is the pile pointer
        for (c = getc(fp); c != EOF; c = getc(fp)) 
                        if (c == '\n') // Increment count if this character is newline 
                                count = count + 1;
        printf("%d\n", count);

        return 0;
}

Перед завершением, Я рекомендую использовать while l oop, так как это часто используется идиома в C для создания более компактной формы вашего l oop:

#include <stdio.h>

int main()
{
        int c;
        long count = 0;
        FILE *fp = stdin; /* probably you dont have intialized this
                           * field in your code, but who knows, if 
                           * you have not posted a complete 
                           * sample */

        // fp is the pile pointer
        while ((c = getc(fp)) != EOF) 
              if (c == '\n') // Increment count if this character is newline 
                 count++; // this is another  frequently used idiom :)

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

        return 0;
}
0 голосов
/ 28 мая 2020

Может быть, ваш файл в конце или по ошибке, когда вы это делаете ?? И начинать нужно с начала

int c;                            // c must be int
int count = 0;
// fp is the pile pointer

rewind(fp);                       // back to beginning, clear error

for (c = getc(fp); c != EOF; c = getc(fp)) 
        if (c == '\n') // Increment count if this character is newline 
            count = count + 1; 
...