Это оператор stl >> функция магия происходит?
У меня странная проблема, когда я тестирую возможности C++ STL. Если я раскомментирую строку if(eee), мой цикл while никогда не завершится.
Я использую vs2015 под 64-битной Windows.
int i = 0;
istream& mystream = data.getline(mycharstr,128);
size_t mycount = data.gcount();
string str(mycharstr,mycharstr+mycount);
istringstream myinput(str);
WORD myfunclist[9] = {0};
for_each(myfunclist,myfunclist+9, [](WORD& i){ i = UINT_MAX;});
CALLEESET callee_set;
callee_set.clear();
bool failbit = myinput.fail();
bool eof = myinput.eof();
while (!failbit && !eof)
{
int eee = myinput.peek();
if (EOF == eee) break;
//if (eee) // if i uncomment this line ,the failbit and eof will always be false,so the loop will never exit.
{
myinput >> myfunclist[i++];
}
//else break;
failbit = myinput.fail();
eof = myinput.eof();
cout << myinput.rdstate() << endl;
}
2 ответа
Я думаю что
int eee = myinput.peek();
в какой-то момент возвращается ноль.
Тогда из-за
if (eee)
Вы прекращаете чтение из потока и никогда не достигаете EOF.
Стараться сделать
if (eee >= 0)
вместо
В качестве альтернативы вы можете сделать:
if (eee < 0)
{
break;
}
// No need for further check of eee - just do the read
myinput >> myfunclist[i++];
Основная причина вашей проблемы - недопонимание того, как потоки устанавливают свои флаги:
fail()
и устанавливаются только после сбоя операции чтения или попытки чтения после достижения последнего байта.
Другими словами, с потоками C++ вы могли полностью прочитать последний байт вашего ввода и оказаться в конце файла, но все же
eof()
останется ложным, пока вы не попытаетесь прочитать больше. В StackOverflow вы найдете много вопросов и ответов о том, почему вам не следует использовать цикл eof в потоке C++.
Последствия:
- Вы всегда будете входить в цикл, даже если в нем нет символа для чтения
myinput
. - Поэтому вам необходимо проверить особый случай возврата
EOF
. - Если вы все еще находитесь в цикле после просмотра, значит, еще есть символы для чтения. Имейте в виду, что
peek()
не потребляет персонажей. Если вы не прочитаете его должным образом, вы останетесь на том же месте в потоке. Итак, если по какой-либо причине вы не достигнетеmyinput >> myfunclist[i++];
, вы застряли в бесконечном цикле, постоянно подглядывая одного и того же персонажа снова и снова. Это случай 0, который хорошо описан в ответе 4386427 : он все еще там, и вы не продвигаетесь в потоке.
Другие комментарии:
- поскольку ваш ввод может иметь длину 128 байт, и вы читаете целые числа в текстовой кодировке, у вас может быть злой ввод с 64 разными словами, что приведет к выходу вашего цикла за границы ов и, например, к повреждению памяти.
- Непонятно, зачем ты вообще пытаешься подглядывать.
Я бы посоветовал забыть о флагах, использовать обычную идиому чтения потока и упростить код, чтобы:
...
callee_set.clear(); // until there, no change
while (i<9 && myinput >> myfunclist[i++])
{
cout << myinput.rdstate() << endl; // if you really want to know ;-)
}