EOF всегда отрицателен? - PullRequest
       11

EOF всегда отрицателен?

7 голосов
/ 26 октября 2009

EOF всегда отрицателен?

Я подумываю написать функцию, которая читает следующее слово на входе и возвращает номер строки, в которой было найдено слово, или EOF, если достигнут конец ввода. Если EOF не обязательно отрицательный, функция будет неправильной.

Ответы [ 6 ]

15 голосов
/ 26 октября 2009

EOF всегда == EOF. Больше ничего не предполагай.

При втором чтении стандарта (и, как и некоторых других комментариев здесь), кажется, что EOF всегда отрицателен - и для использования, указанного в этом вопросе (номер строки или EOF), это будет работать. Что я хотел предупредить (и до сих пор делаю), так это предположить, что символы положительные, а EOF - отрицательные.

Помните, что стандартная реализация C может иметь отрицательные символьные значения - это даже упоминается в «Языке программирования C» (K & R). Печать символов всегда положительна, но на некоторых архитектурах (вероятно, все древние) управляющие символы отрицательны. Стандарт C не указывает, является ли тип char подписанным или неподписанным, и единственная символьная константа, гарантированно имеющая одинаковое значение для разных платформ, - это '\0'.

10 голосов
/ 26 октября 2009

Да, EOF всегда отрицательно.

Стандарт гласит:

7.19 Вход / выход
7.19.1 Введение

3 Макросы [...] EOF, которые расширяется до целочисленной константы выражение, с типом int и отрицательное значение, которое возвращается несколько функций для указания конец файла, то есть больше нет ввода из ручья;

Обратите внимание, что нет проблем с подписью "plain" char. Функции <stdio.h>, которые имеют дело с char s, специально приводят символы к unsigned char, а затем к int, так что все действительные символы имеют положительное значение. Например:

int fgetc(FILE *stream)

7.19.7.1
... функция fgetc получает этот символ как беззнаковый символ, преобразованный в int ...

8 голосов
/ 26 октября 2009

Эта функция возвращает

  • номер строки, в которой было найдено слово
  • или -1, если достигнут конец ввода

Проблема решена без необходимости полагаться на какие-либо значения EOF. Вызывающий может легко проверить, больше или равен нулю для успешного вызова, и в противном случае принять ошибку EOF / IO.

2 голосов
/ 26 октября 2009

Из онлайн-черновика n1256 , 17.9.1.3:

EOF

, который расширяется до целочисленного константного выражения с типом int и отрицательным значением, это возвращается несколькими функциями, чтобы указать конец файла , то есть больше нет ввода из ручья;

EOF всегда отрицателен, хотя не всегда может быть -1.

Для подобных проблем я предпочитаю отделять условия ошибок от данных, возвращая код ошибки (SUCCESS, END_OF_FILE, READ_ERROR и т. Д.) В качестве возвращаемого значения функции, а затем записывая интересующие данные в отдельные параметры, такие как

int getNextWord (FILE *stream, char *buffer, size_t bufferSize, int *lineNumber)
{
  if (!fgets(buffer, bufferSize, stream))
  {
    if (feof(stream)) return END_OF_FILE; else return READ_ERROR;
  }
  else
  {
    // figure out the line number
    *lineNumber = ...;
  }
  return SUCCESS;
}      
1 голос
/ 26 октября 2009

Из Википедия :

Фактическое значение EOF является системно-зависимое отрицательное число, обычно -1, что гарантированно будет не соответствует действительному коду символов.

Но нет ссылок ...

Из безопасного кодирования: Обнаружение и обработка ошибок ввода и вывода EOF отрицателен, но только когда sizeof (int)> sizeof (char) .

1 голос
/ 26 октября 2009

EOF - это условие, а не значение. Точное значение этого стража определяется реализацией. Во многих случаях это отрицательное число.

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