Прочтите, пожалуйста, Как создать минимальный, полный и проверяемый пример .
Чтобы протестировать фрагмент вашей программы, мне сначала нужно было завершить ваш фрагмент кода, чтобы это компилируемый. Вероятно, ваша ошибка исчезла с этими изменениями, поскольку мой запуск показывает (над вашим входным текстом) этот вывод:
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;
}