Первая пара фактов:
- Символ
EOF
- это макрос, который расширяется до целочисленной константы -1
. Эта целочисленная константа будет иметь тип int
.
- Это определяется реализацией, если
char
подписано или не подписано. Один и тот же компилятор на разных платформах может иметь разные реализации char
.
Теперь длинное объяснение вашей проблемы:
Когда целые типы различных размеров используются в арифметических выражениях (а сравнение считается арифметическим оператором), тогда оба операнда выражения подвергаются обычному арифметическому преобразованию для получения общего тип (обычно int
).
Для целочисленных типов меньшего размера, таких как, например, char
, которые включают целочисленное продвижение для преобразования его в int
. Для этой акции значение char
должно быть сохранено, например, -1
как char
будет по-прежнему -1
как int
.
Из-за того, как отрицательные числа представлены в большинстве систем, значение char
-1
равно (в шестнадцатеричном) 0xff
. Для char
со знаком, когда -1
преобразуется в int
, он сохраняет значение -1
(которое будет представлено как 0xffffffff
для 32-битного int
типа).
Проблема возникает, когда char
равен без знака , потому что тогда, когда getchar
возвращает EOF
(значение -1
), значение без знака char
будет равно 255
( десятичное представление без знака 0xff
). И когда повышен до int
значение будет все еще будет 255
. И 255 != -1
!
Вот почему тип возвращаемого значения getchar
равен int
, а не char
. И одна из причин, по которой все функции обработки символов используют int
вместо char
.
Итак, чтобы решить вашу проблему, вам нужно изменить тип переменной c
на int
:
int c;
Тогда будет работать