我正在尝试从用户那里获得输入,并且需要知道一种方法让程序识别输入 或不是是double / char这是我现在拥有的......但是当你输入错误的输入类型时
1)双重测试只是无限循环
2)即使使用正确的输入
,char也不会停止循环int main () {
double _double = 0;
bool done = true;
while ( done ) {
cout << "Please enter a DOUBLE:\n" << endl;
cin >> _double;
if ( _double > 0 ) { done = false; }
if ( _double < 0 ) { cout << "\nthe number you entered was less than zero\nplease enter a valad number..." << endl; }
if(cin.fail()) { cin.clear(); }
}
done = false;
char _char = ' ';
while ( !done ) {
cout << "Please enter a CHAR" << "\n";
cout << "\t'y' = yes\n\t'n' = no" << endl;
cin >> _char;
if ( _char == 'y' || _char == 'n' ) { done = true; }
if ( ! (_char == 'y' || _char == 'n') ) { cout << "\nyou have entered an invald symbol... \n" << endl; }
if(cin.fail()) { cin.clear(); }
}
答案 0 :(得分:5)
最好的选择是将输入作为字符串读取。然后,您可以使用std::strtod()
之类的函数来测试并转换为双精度数。检查流是否已经失败然后重置它们最多容易出错,并且不会让您产生良好的错误消息。
例如:
string s;
cin >> s;
char * p;
double d = strtod( s.c_str(), & p );
if ( * p == 0 ) {
cout << "Read double: " << d << endl;
}
else {
cout << "Read string: " << s << endl;
}
指针'p'将指向无法转换为double的第一个字符。你究竟如何处理这取决于你的应用程序的逻辑。
答案 1 :(得分:3)
问题在于,当你阅读某些东西并且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
(文件/流的末尾),则表示该字符串仅包含一个double。
std::string line;
while(!getline(std::cin, line) || !checkForDouble(line))
std::cout << "Please enter a double instead" << std::endl;
对于char,您只需测试长度1
std::string line;
while(!getline(std::cin, line) || line.size() != 1)
std::cout << "Please enter a double instead" << std::endl;
如果你想只读 1个字符并在输入字符后立即继续,那么你将不得不使用平台相关函数(C ++不会将它们作为标准函数提供)。例如,请注意用于Windows的 conio.h 文件,该文件具有_getch
功能。在unix系统上, ncurses 提供了这样的功能。
答案 2 :(得分:2)
cin >> _double
总会让你双倍。您需要将用户输入作为字符串读取,然后测试该字符串以查看它是否为double。如果sscanf无法将输入字符串转换为所需类型,则返回0:
cout << "Please enter a DOUBLE:\n" << endl;
string s;
cin >> s;
if( !sscanf(s.c_str(), "%lf", &_double) )
{
done = false;
cout << "Not a number, sparky. Try again." << endl;
continue;
}
此外,语言会保留带有前导下划线的标识符。不要养成命名_double
之类的习惯 - 有一天,它们可能无效。