.eof () цикл не работает - PullRequest
       4

.eof () цикл не работает

2 голосов
/ 05 января 2012

Я пытаюсь читать числа из файла и помещаю их в массив.Прямо сейчас, когда я запускаю программу, она печатает 8 цифр, затем строка заканчивается и печатает те же 8 цифр.Это в бесконечном цикле.Что я делаю не так?

#include <iostream>                                                             
#include <fstream>                                                              
using namespace std;                                                            

int main()                                                                      
{                                                                               
  int num;                                                                      
  ifstream infile;                                                              
  infile.open("euler8Nums.txt");                                                
    infile >> num;//must attempt to read info prior to an eof() test            
    while(!infile.eof()){                                                       
      cout << num << endl;                                                      
      infile >> num;                                                            
    }                                                                           
    infile.close();                                                             
    return 0;                                                                   
}  

Ответы [ 2 ]

11 голосов
/ 05 января 2012

Как правило, не используйте .eof() или .bad().Просто проверьте состояние самого потока

while (infile >> num)
    cout << num << endl;

Флаг eof не будет установлен, если поток не сможет проанализировать вход, а затем поток перестанет работать, пока состояние не будет очищено.Если вы проверите bad вместо этого, он будет работать до тех пор, пока не сможет выполнить синтаксический анализ, но при этом произойдет ошибка в EOF.Так что просто проверьте, является ли поток все еще .good() (что неявно, когда он находится в цикле while).

В вашем случае это бесконечный цикл, потому что файл не открылся и затем вы пытаетесь прочитать цифры, но чтение ничего не делает , потому что файл не открыт.Таким образом, он никогда не читает eof, то есть бесконечный цикл.

4 голосов
/ 05 января 2012

Я не знаю, что содержит ваш файл или как это вызвало бы бесконечный цикл печати больше, чем последний номер.Тем не менее, бит eof() подходит только для сообщений об ошибках, а not - для управления циклом.Кроме того, в коде есть много других вещей, которые совершенно не нужны.Следующая программа должна прочитать числа ОК:

#include <iostream>                                                             
#include <fstream>                                                              

int main()                                                                      
{                                                                               
    std::ifstream infile("euler8Nums.txt");
    for (int num; infile >> num; )
        std::cout << num << "\n";
    return 0;
}

Я никогда не видел точки при вызове open() отдельно, если нет необходимости в условных выражениях, прежде чем можно будет определить имя файла.Аналогичным образом, вызов close() явно кажется довольно бессмысленным, если только вы не хотите проверить, что закрытие было успешным (хотя я не уверен, что close() во входном потоке может потерпеть неудачу).

Другоймоей любимой мозоли является ненужное использование std::endl: этот манипулятор является относительно частым источником плохой работы!Он делает две вещи:

  1. Он записывает символ конца строки, то есть \n (или, в широких символьных потоках, результат расширения этого символа).
  2. Он сбрасываетпоток.На файловых потоках это довольно дорогая операция, которая может легко замедлиться, что является существенным фактором (не только на несколько процентов).Фактические записи часто преобладают над фактической производительностью кода, записывающего данные в файл в режиме реального времени.

Сбрасывать поток только тогда, когда вы действительно этого хотите.Если вы чувствуете, что вам нужны дополнительные очистки в потоке, например, при попытке найти то, что написано прямо перед сбоем, просто установите std::unitbuf для объекта потока: это будет хуже с точки зрения производительности, потому что он очищает потокпосле каждой вставки, но легко удаляется, как только обнаруживается проблема.

Конечно, результирующая программа может быть изменена на нечто более аккуратное, например

#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>

int main()
{
    std::copy(std::istream_iterator<int>(std::ifstream("euler8Nums.txt") >> std::ws),
              std::istream_iterator<int>(), std::ostream_iterator<int>(std::cout, "\n"));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...