EOF не обнаружен C на Raspberry Pi - PullRequest
2 голосов
/ 15 марта 2019

Итак, я писал на своем Raspberry Pi Zero программу для подсчета частот разных длин слов на входе, но программа не остановилась на EOF.

Итак, я попытался отладить:

#include <stdio.h>
#include <stdlib.h>

void main() {
    char c;
    while ( (c = getchar()) != EOF) {
        putchar(c);
    }
}

И скомпилировано с этим:

gcc test.c && ./a.out <input.txt

Он распечатывал введенный текст, но затем просто продолжал печатать вопросительные знаки, пока я не нажал Ctrl + C. Когда я скопировал программу на свой ноутбук и запустил там, все работало нормально.

Я мог бы просто закончить на ноутбуке, но мне любопытно. Почему Pi не может обнаружить, когда файл нажал EOF?

Ответы [ 3 ]

3 голосов
/ 15 марта 2019

Первая пара фактов:

  • Символ 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;

Тогда будет работать

2 голосов
/ 15 марта 2019

getchar возвращает int значение, а не char значение.Поскольку вам нужен какой-то способ распознавания в одной getchar функции, если вы читаете обычный символ или если функция говорит вам, что читать больше нечего - кто-то давно решил использовать int, чтобы какое-то значение, большее char, моглобыть возвращен, чтобы указать конец файла.Измените char на int.

1 голос
/ 15 марта 2019

getchar's return value должен иметь возможность возвращать любой символ ASCII (и расширенный ASCII) в диапазоне от 0 до 255.

Чтобы сделать различие между ascii и EOF, EOF не может быть значением вэтот интервал, поэтому тип возвращаемого значения getchar должен иметь более 8 бит.

   int getchar(void);

Таким образом, вы должны написать

int c;
while ( (c = getchar()) != EOF) ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...