Как узнать, является ли следующий символ EOF в C++

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

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

и

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

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

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

7 ответов


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() быть false не означает, что следующая операция чтения будет успешной.


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

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

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


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

peek() совершенно не вижу. :-)


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

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


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


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

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

еще один такой способ реализовать это было бы..

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

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


вы не показали никакого кода, с которым работаете, поэтому есть некоторые догадки с моей стороны. Обычно вам не нужны низкоуровневые объекты (например,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;