-2

Нужно в цикле читать слово из файла. Цикл должен работать до тех пор, пока в файле есть строки. Читаю строки так:

std::ifstream val("val.txt"); 
char val2[16] ; 
val >> val2;
  • Ну давайте начнем. Как вы просто будете читать строки? Пока отложим в сторону "пока они есть". Как вы прочтете строку из файла? – Harry Jan 22 '18 at 17:59
  • Похож: https://ru.stackoverflow.com/questions/290919/%d0%a7%d1%82%d0%b5%d0%bd%d0%b8%d0%b5-%d1%81%d1%82%d1%80%d0%be%d0%ba-%d0%b8%d0%b7-%d1%84%d0%b0%d0%b9%d0%bb%d0%b0?rq=1 и тут: https://ru.stackoverflow.com/questions/74601/%d0%a7%d1%82%d0%b5%d0%bd%d0%b8%d0%b5-%d1%81%d1%82%d1%80%d0%be%d0%ba-%d0%b8%d0%b7-%d1%84%d0%b0%d0%b9%d0%bb%d0%b0?rq=1 –  Jan 22 '18 at 18:05
  • @VladSpirin Нужного ответа там нет. – Rob Clark Jan 22 '18 at 18:17
  • В ответе вы не читаете, а пытаетесь вывести. И не строки, а слова :) Намекаю - посмотрите в сторону функции getline. – Harry Jan 22 '18 at 18:19
  • @Harry Как отследить момент, после которого уже не надо читать? – Rob Clark Jan 22 '18 at 18:28
  • На всякий случай еще раз: вот так - val >> val2; - вы читаете не строку, а слово. Если вас устраивает чтение не по строкам, а по словам - можно и так. Но опасно - слово может быть длиннее, чем ваш буфер. Но опять же - что возвращает инструкция val >> val2;? – Harry Jan 22 '18 at 18:43

2 Answers2

2

Проверяйте на успешность каждую операцию чтения:

ifstream file("val.txt");
for (string word; file >> word; ) 
  ; // здесь что-то с word можно сделать

Цикл заканчивается когда произошла ошибка либо наступил конец файла. Никаких file.eof() нет в условии цикла. Только после цикла, после чтения имеет смысл вызвать file.eof(), чтобы узнать наступил ли конец файла. К примеру, чтобы вернуть статус возврата из main():

return !file.eof(); // успех, если дошли до конца файла

Для чтения строк можно использовать getline():

while(getline(cin, line)) // count words
    ++counter[line];

if (!cin.eof())
    return 1; // I/O error

Обратите внимание, возвращаемое значение getline() проверяется после каждого вызова, cin.eof() внутри цикла чтения не используется и вызывается после окончания чтения. Если конец файла не достигнут, то это считается ошибкой в этом случае.


Аналогично при неявных >>-операциях. К примеру, чтобы найти слово в файле, можно использовать istream_iterator<>:

ifstream file("input.txt");
istream_iterator<string> eof;
bool found = find(istream_iterator<string>(file), eof, word) != eof;

Снова, file.eof() при чтении файла не используется. Можно в конце вызвать .eof() метод, чтобы узнать произошла ли ошибка:

int main() {
    ...
    return found ? 0 : (cin.eof() ? 1 : 2);
}

В этом случае, нулевой статус означает что слово найдено, а cin.eof() позволяет различить случаи когда слово не присутствует (возвращается 1) от случая когда ошибка произошла (возвращается 2) -- как это grep утилита может делать.

jfs
  • 52,361
0

Скорее всего автор пытался сказать, как проверить, закончился ли файл:

if(val.eof())
   break;

И да, читаете Вы слово, а не строку.

Range
  • 2,693
  • 1
    Вообще-то все куда проще - while(val>>val2){...}. А с проверкой eof() - вечная проблема, потому как ее начинают использовать как while(!val.eof()){...}, а потом сюда вопросы пишут, почему не работает... – Harry Jan 22 '18 at 19:43
  • @Harry, вроде бы в каждом учебнике пишут, что проверять следует после конца файла. – Range Jan 22 '18 at 19:47
  • @Range: Что значит "проверять следует после конца файла"? Если мы уже "после конца файла", то зачем проверять? Это во-первых. Во-вторых, в С/С++ коде чтения файла обычно не должно быть прямых проверок на eof. Проверки на eof нужны только в коде обработки ошибочной ситуации - чтобы выяснить, что именно произошло. – AnT stands with Russia Jan 22 '18 at 19:51
  • @AnT объясняю, как это понял я. Есть цикл для чтения строк из файла. Читаем строку, затем проверяем файл на конец, записываем строку куда-то в буфер. Т.е., при очередном считывании из файла в строку ничего не считается, т.к. файл кончится и последующая проверка выведет нас из цикла. – Range Jan 22 '18 at 19:53
  • 3
    @Range: Ну то есть вы хотели сказать "проверять следует после чтения", а не ваше странное "проверять следует после конца файла". Но в общем случае это - неправильный подход. Вы сделали операцию чтения, после нее вдруг увидели статус eof. О чем это вам говорит? Прочиталось ли что либо вообще или нет? Как вы это выясните? Вот именно поэтому все операции чтения сами тем или иным образом возвращают статус успешности, который и надо проверять. А не eof. – AnT stands with Russia Jan 22 '18 at 19:56
  • @AnT вообще задумался, да, быть может и было что-то считано, а у нас уже eof. Городить кучу проверок явно лишнее. И спасибо за науку. – Range Jan 22 '18 at 20:00