При вставке письмо это происходит:
operator>>
извлекает символы из потока и попытаться преобразовать их в ряд;
- сбой при преобразовании, поэтому он устанавливает состояние потока
ios::failbit
и возвращает; opt
, вероятно, нетронутый (стандарт делегирует этот материал библиотеке локалей, которая является зоной C++, которую я никогда не понимал - для достаточно храбрых, это в §22.2.2.1.2);
- с тех пор, как он вернулся и (возможно)
opt
оставлен как есть, цикл продолжается;
- , когда выполнение возвращается к
std::cin >> opt;
, operator>>
видит, что состояние по-прежнему ios::failbit
, поэтому оно даже не пытается извлечь что-либо;
- Гото 3.
Чтобы устранить эту проблему, вы должны очистить состояние ошибки и устранить «неправильные» символы из входного буфера. Поскольку вы, вероятно, не хотите добавлять весь этот код к каждому cin>>
, полезно создать функцию для решения этой общей проблемы; лично я создал этот маленький заголовок (AcquireInput.hpp
), которая доказала свою полезность во много раз:
#ifndef ACQUIREINPUT_HPP_INCLUDED
#define ACQUIREINPUT_HPP_INCLUDED
#include <iosfwd>
#include <limits>
#include <string>
template<typename InType> void AcquireInput(std::ostream & Os, std::istream & Is, const std::string & Prompt, const std::string & FailString, InType & Result)
{
do
{
Os<<Prompt.c_str();
if(Is.fail())
{
Is.clear();
Is.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Is>>Result;
if(Is.fail())
Os<<FailString.c_str();
} while(Is.fail());
}
template<typename InType> InType AcquireInput(std::ostream & Os, std::istream & Is, const std::string & Prompt, const std::string & FailString)
{
InType temp;
AcquireInput(Os,Is,Prompt,FailString,temp);
return temp;
}
/* Usage example:
//1st overload
int AnInteger;
AcquireInput(cout,cin,"Please insert an integer: ","Invalid value.\n",AnInteger);
//2nd overload (more convenient, in this case)
int AnInteger=AcquireInput(cout,cin, "Please insert an integer: ","Invalid value.\n");
*/
#endif
Когда вы говорите, «передать письмо», вы имеете в виду вы читаете 'char'? Или вы хотите ввести письмо при запуске вышеуказанного кода? – marcog
Посмотрите, поможет ли это. http://stackoverflow.com/questions/4342068/c-infinite-loop-with-a-simple-menu-selection/4342247#4342247 –
да, я читаю символ, но cin ждет int –