Проблема в том, что когда вы что-то читаете и cin
видит, что ввод никогда не может быть двойным, он прекращает чтение, оставляя содержимое в буфере, который он не использовал. Он будет сигнализировать о сбое, который вы очистите, но вы не будете есть оставшиеся данные, которые cin
не съели. Итак, в следующий раз тот же неправильный ввод снова будет прочитан, и снова ...
Проблема с char
в том, что вам нужно нажать клавишу возврата, чтобы он обрабатывал любые символы на большинстве терминалов (этого не происходит, если вы, например, заставляете вашу программу читать из файла). Поэтому, если вы нажмете y
, он не выйдет из вызова на чтение, пока вы не нажмете клавишу возврата. Тем не менее, тогда он будет продолжаться и выйдет из цикла.
Как уже упоминали другие, вам лучше прочитать целую строку, а затем решить, что делать. Вы также можете проверить число с потоками C ++ вместо функций C:
bool checkForDouble(std::string const& s) {
std::istringstream ss(s);
double d;
return (ss >> d) && (ss >> std::ws).eof();
}
Это читает любой начальный двойной номер и затем любой оставшийся пробел. Если он затем нажмет eof
(конец файла / потока), это означает, что строка содержит только двойное число.
std::string line;
while(!getline(std::cin, line) || !checkForDouble(line))
std::cout << "Please enter a double instead" << std::endl;
Для символа вы можете просто проверить длину 1
std::string line;
while(!getline(std::cin, line) || line.size() != 1)
std::cout << "Please enter a double instead" << std::endl;
Если вы хотите прочитать only 1 char и продолжить, как только этот char был напечатан, вам придется использовать зависимые от платформы функции (C ++ не будет предоставлять их в качестве стандартных функций). Найдите, например, файл conio.h для Windows, для которого есть функция _getch
. В системах Unix ncurses обеспечивает такую функциональность.