Как узнать, является ли следующий символ EOF в C ++ - PullRequest
10 голосов
/ 08 июня 2011

Мне нужно знать, является ли следующий символ в ifstream концом файла.Я пытаюсь сделать это с .peek():

if (file.peek() == -1)

и

if (file.peek() == file.eof())

Но ни один не работает.Есть способ сделать это?

Редактировать: Я пытаюсь добавить букву в конец каждого слова в файле.Для этого я спрашиваю, является ли следующий символ пунктуацией, но в этом случае последнее слово остается без лишней буквы.Я работаю только с char, а не string.

Ответы [ 7 ]

22 голосов
/ 08 июня 2011

istream::peek() возвращает константу EOF (которая не гарантированно равна -1) при обнаружении конца файла или ошибки . Для надежной проверки конца файла сделайте следующее:

int c = file.peek();
if (c == EOF) {
  if (file.eof())
    // end of file
  else
    // error
} else {
  // do something with 'c'
}

Вы должны знать, что базовый примитив ОС, read(2), сигнализирует EOF только при попытке прочитать за конец файла. Следовательно, file.eof() не будет истинным, если вы просто прочитали до последнего символа в файле. Другими словами, file.eof(), будучи ложным, не означает, что следующая операция чтения будет успешной.

8 голосов
/ 08 июня 2011

Это должно работать:

if (file.peek(), file.eof())

Но почему бы просто не проверить ошибки после попытки прочитать полезные данные?

2 голосов
/ 08 июня 2011

Для потока, подключенного к клавиатуре, условие eof состоит в том, что я намерен набрать Ctrl + D / Ctrl + Z во время следующего ввода.

peek() совершенно не может этого увидеть.: -)

1 голос
/ 08 июня 2011

Невозможно определить, является ли следующий символ концом файла, и попытка сделать это - одна из самых распространенных ошибок, которые делают новые программисты на C и C ++, потому что в конце нет символа конца файла. большинство операционных систем. То, что вы можете сказать, это то, что чтение после текущей позиции в потоке будет читать после конца файла, но в целом это довольно бесполезная информация. Вместо этого вам следует проверить все операции чтения на успешность или неудачу и действовать в этом состоянии.

1 голос
/ 08 июня 2011

file.eof() возвращает значение флага.Он установлен в TRUE, если вы больше не можете читать из файла.EOF - не настоящий персонаж, это маркер для ОС.Поэтому, когда вы там - file.eof() должно быть true.

Итак, вместо if (file.peek() == file.eof()) у вас должно быть if (true == file.eof()) после чтения (или просмотра), чтобы проверить, достиг ли вы концафайл (это то, что вы пытаетесь сделать, если я правильно понимаю).

0 голосов
/ 08 июня 2011

Вы не показывали ни одного кода, с которым работаете, поэтому есть некоторые предположения с моей стороны. Обычно вам не нужны средства низкого уровня (например, peek()) при работе с потоками. То, что вы, вероятно, заинтересованы в istream_iterator. Вот пример,

  cout << "enter value";

  for(istream_iterator<double> it(cin), end; 
      it != end; ++it)
  {
     cout << "\nyou entered value " << *it;
     cout << "\nTry again ...";
  }

Вы также можете использовать istreambuf_iterator для прямой работы с буфером:

  cout << "Please, enter your name: ";

  string name;
  for(istreambuf_iterator<char> it(cin.rdbuf()), end;
    it != end && *it != '\n'; ++it)
  {
    name += *it;
  }
  cout << "\nyour name is " << name;
0 голосов
/ 08 июня 2011

Обычно для проверки конца файла я использовал:

    if(cin.fail())
    {
        // Do whatever here
    }

Еще один способ реализовать это будет ..

    while(!cin.fail())
    {
        // Do whatever here
    }

Дополнительная информация будет полезна, чтобы мы знали, что вы хотите сделать.

...