当输入声明为double时,检查输入是否为空[C ++]

时间:2009-08-27 17:15:00

标签: c++ null double

我有三个声明为双精度的变量:

double Delay1 = 0;
double Delay2 = 0;
double Delay3 = 0;

我然后从用户那里获取他们的值:

cout << "Please Enter Propogation Delay for Satellite #1:";  
cin >> Delay1;
...

但是当我检查这些值以查看它们是否为空(用户只需按Enter并且没有输入数字)时它不起作用:

if(Delay1  || Delay2 || Delay3 == NULL)  
      print errror...

每次都会运行 检查已声明为double的输入是否为空的正确方法是什么?

8 个答案:

答案 0 :(得分:11)

这样的东西
cin >> Delay1;
if(cin) { ... }

将无法按照您的规范运行,因为cin将跳过前导空格。用户不能只是按Enter键。他首先必须输入一些文字。如果他进入以下

3a

然后将输入读入双精度数,直至a,然后停止。 cin不会发现任何错误,并在流中留下a。通常,这是足够的错误处理,我认为。但是,如果要求您在用户输入上述内容时实际重复,则需要更多代码。

如果你想测试直到换行符的整个输入是否为数字,那么你应该使用getline,读入一个字符串,然后尝试转换为数字

string delay;
if(!getline(std::cin, delay) || !isnumber(delay)) {
  ...
}

isnumber函数可以使用字符串流来测试字符串

bool isnumber(string const &str) {
  std::istringstream ss(str);
  double d;

  // allow leading and trailing whitespace, but no garbage
  return (ss >> d) && (ss >> std::ws).eof();
}

operator>>将占用前导空格,std::ws将占用尾随空格。如果它到达流的末尾,它将发出eof信号。这样,您可以立即向用户发出错误信号,而不是在您下次尝试从cin读取错误时。

写一个类似的函数,它返回double或将double的地址传递给`isnumber,这样它就可以在成功解析的情况下写出结果。


还有必要查看各种错误标记以及它们与operator void*operator!good()fail()bad()eof()这可能会令人困惑:

            flag | badbit  |  failbit  |  eofbit
function         |         |           |
-----------------+---------+-----------+--------
op void*         |    x    |     x     |
-----------------+---------+-----------+--------
op !             |    x    |     x     |
-----------------+---------+-----------+--------
good()           |    x    |     x     |    x
-----------------+---------+-----------+--------
fail()           |    x    |     x     |
-----------------+---------+-----------+--------
bad()            |    x    |           |
-----------------+---------+-----------+--------
eof()            |         |           |    x
-----------------+---------+-----------+--------

如果相应的位影响结果,则有x。转换为operator void*bool)时使用if(cin) ...operator!用于代码执行!cin

答案 1 :(得分:4)

std::cout << "Enter doubles: ";
std::cin >> d1 >> d2 >> d3;

if(std::cin.fail())
{
    // error!
}

答案 2 :(得分:3)

检查流输入是否有效的方法是测试流:

if(!std::cin) throw "Doh!";

由于operator>>总是返回其左参数,因此也适用:

if( std::cin >> Delay1 ) 
  good();
else
  bad();

如果输入失败,输入流不会改变值。在您的情况下,他们将保留以前的随机值。如果没有检查流,你永远不应该接受输入。

答案 3 :(得分:3)

您需要检查的是在尝试读取double后输入流的状态。

例如

cin >> Delay1;
if (!cin.fail()) {
  // Input was a double
} else {
  // Input was something that could not be interpreted as a double
}

你可以更简洁地写下这个

if (cin >> Delay1) {
  // Input was a double
} else {
  // Input was something that could not be interpreted as a double
}

如果输入失败,则Delay1的值不会改变,因此如果您之前没有初始化它,它将是一些任意值。正如已经指出的那样,它不会变成“NULL”,因为只有指针可以为null,而不是值类型。

答案 4 :(得分:2)

这里出现了多种问题。

首先:检查解析是否失败,使用if (cin.fail()) { /* print error */ }

第二:Delay1 || Delay2 || Delay3会将双精度转换为布尔值,然后将它们逻辑或运算在一起。

第三:== NULL会将您的布尔值(在本例中为false)与指针值NULL进行比较。我相信这将永远是true

答案 5 :(得分:2)

你的条件错了。如果延迟等于零或者延迟2 等于零或者Delay3为零,则if(Delay1 || Delay2 || Delay3 == NULL)为真。当然这不是你想要的。您还应该使用0作为原始数据类型。此外,将双值与绝对值进行比较总是危险的。您可以检查该值是否小于一个小的epsilon值。

答案 6 :(得分:1)

只使用流状态,如果它无法读取双精度数,它将处于失败状态。

if(!(std::cin >> Delay1 >> Delay2 >> Delay3)) {
    // error
}

答案 7 :(得分:0)

我认为您需要以字符串形式读取变量,然后检查它是否为空,然后将其转换为double(并检查它是否为有效的双精度 - 用户可能只是键入了“hello”)。