简体   繁体   English

C++ 测试输入是否为双精度/字符

[英]C++ test if input is an double/char

I am trying to get input from the user and need to know a way to have the program recognize that the input was or was not a double/char this is what i have right now... but when you type an incorrect type of input我正在尝试从用户那里获取输入,并且需要知道一种让程序识别输入不是双精度/字符的方法,这就是我现在所拥有的……但是当您输入的输入类型不正确时

1) the double test one just loops infinatly 1)双重测试只是无限循环

2) the char one won't stop looping even with the correct imput 2)即使输入正确,字符也不会停止循环

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(); }
}

The best bet is always to read your input as strings.最好的办法是始终将您的输入读取为字符串。 You can then use functions like std::strtod() to test and convert to doubles.然后,您可以使用std::strtod()类的函数来测试并转换为双精度数。 Checking if streams have failed and then resetting them is error prone at best, and doesn't give you the possibility of producing good error messages.检查流是否失败然后重置它们充其量是容易出错的,并且不会给您产生好的错误消息的可能性。

For example:例如:

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;
}

The pointer 'p' will point to the first character that cannot be converted to a double.指针“p”将指向第一个不能转换为双精度的字符。 How exactly you handle that really depends on your app's logic.您如何处理这实际上取决于您的应用程序的逻辑。

The problem is that when you read something and cin sees the input can never be a double, it stops reading, leaving the stuff in the buffer that it didn't consume.问题在于,当您读取某些内容并且cin看到输入永远不会是双精度值时,它会停止读取,将未消耗的内容留在缓冲区中。 It will signal failure, which you clear but you won't eat the remaining input that cin didn't eat up.它会发出失败的信号,你清除了它,但你不会吃掉cin没有吃掉的剩余输入。 So, the next time the same wrong input is tried to read again, and again...因此,下次尝试再次读取相同的错误输入时,再次......

The problem with the char one is that you have to press the return key to make it process any characters on most terminals (this does not happen if you make your program read from a file, for instance). char one 的问题是您必须按返回键才能使其处理大多数终端上的任何字符(例如,如果您让程序从文件中读取,则不会发生这种情况)。 So if you press y then it won't go out of the read call, until you hit the return key.因此,如果您按y则它不会退出 read 调用,直到您按下返回键。 However, then it will normally proceed and exit the loop.但是,它通常会继续并退出循环。

As others mentioned you are better off with reading a whole line, and then decide what to do.正如其他人所说,您最好阅读整行,然后再决定要做什么。 You can also check the number with C++ streams instead of C functions:您还可以使用 C++ 流而不是 C 函数检查数字:

bool checkForDouble(std::string const& s) {
  std::istringstream ss(s);
  double d;
  return (ss >> d) && (ss >> std::ws).eof();
}

This reads any initial double number and then any remaining whitespace.这将读取任何初始双数,然后读取任何剩余的空格。 If it then hit eof (end of the file/stream), it means the string contained only a double.如果它随后命中eof (文件/流的结尾),则表示该字符串仅包含一个双精度值。

std::string line;
while(!getline(std::cin, line) || !checkForDouble(line)) 
  std::cout << "Please enter a double instead" << std::endl;

For the char, you can just test for length 1对于字符,您可以只测试长度 1

std::string line;
while(!getline(std::cin, line) || line.size() != 1) 
  std::cout << "Please enter a double instead" << std::endl;

If you want to read only 1 char and continue as soon as that char was typed, then you will have to use platform dependent functions (C++ won't provide them as standard functions).如果你想读的只有1字符,并尽快为字符键入了继续,那么你将不得不使用的平台相关的功能(C ++不会将它们作为标准功能)。 Look out for the conio.h file for windows for instance, which has the _getch function for this.例如,注意 windows 的conio.h文件,它具有_getch函数。 On unix systems, ncurses provides such functionality.在 unix 系统上, ncurses提供了这样的功能。

cin >> _double will always get you a double, whether they typed in "42", "0" or "mary had a little lamb". cin >> _double总是cin >> _double你一个double,无论他们输入的是“42”、“0”还是“mary had a little lamb”。 You need to read the user input as a string, then test that string to see if it is a double.您需要将用户输入读取为字符串,然后测试该字符串以查看它是否为双精度值。 sscanf will return 0 if it can't convert the input string to the desired type:如果 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;
    }

Also, identifiers with leading underscores like you have are reserved by the language.此外,像您这样带有前导下划线的标识符由语言保留。 Don't get in the habit of naming things like _double -- someday, they may not work.不要养成像_double这样命名的习惯——总有一天,它们可能不起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM