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

发布于 2024-08-03 07:41:39 字数 437 浏览 2 评论 0原文

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

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

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

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

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

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

这会运行每个时间。
检查已声明为双精度的输入是否为空的正确方法是什么?

I have three variable declared as doubles:

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

I Then get their values from the user:

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

But when I check these values to see if they are null (user just hit enter and did not put a number) it doesn't work:

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

This runs every time.
What is the proper way to check if an input that has been declared a double is blank?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

又爬满兰若 2024-08-10 07:41:39

类似的东西

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 读取时出错。

编写一个类似的函数,返回双精度型或将双精度型的地址传递给“isnumber”,以便在解析成功时可以写入结果。


还值得查看各种错误标志以及它们与 operator void*operator!good()、< code>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
-----------------+---------+-----------+--------

如果各个位影响结果。 operator void* 在转换为 bool (if(cin) ...) 时使用,而 operator! 是用于执行 !cin 的代码

Something like

cin >> Delay1;
if(cin) { ... }

won't work according to your specification, because cin will skip leading whitespace. The user can't just hit enter. He first has to enter some text. If he enters the following

3a

Then the input is read into the double, up to a, where it stops. cin won't find anything wrong, and leaves a in the stream. Often, this is enough error handling, i think. But if it's a requirement that you want to actually repeat when the user enters something like above, then you need a bit more code.

If you want to test whether the whole input up to the newline is a number, then you should use getline, read into a string and then try to convert to a number

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

The isnumber function can use a stringstream to test the string

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

The operator>> will eat leading whitespace, and std::ws will consume trailing whitespace. If it hits to the end of the stream, it will signal eof. This way, you can signal the error to the user immediately, instead of erroring out at the next time you try to read from cin.

Write a similar function that returns the double or pass the address of a double to `isnumber, so that it can write the result in case of a successful parse.


It's also worth to have a look at the various error flags and how they relate to operator void*, operator!, good(), fail(), bad() and eof() which can be quite confusing:

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

There is an x if the respective bit influences the result. operator void* is used when converting to bool (if(cin) ...) while operator! is used for code doing !cin

假情假意假温柔 2024-08-10 07:41:39
std::cout << "Enter doubles: ";
std::cin >> d1 >> d2 >> d3;

if(std::cin.fail())
{
    // error!
}
std::cout << "Enter doubles: ";
std::cin >> d1 >> d2 >> d3;

if(std::cin.fail())
{
    // error!
}
一影成城 2024-08-10 07:41:39

在尝试读取双精度数据后,您需要检查的是输入流的状态。

例如,

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”,因为只有指针可以为空,而值类型则不能。

What you need to check is the state of the input stream after you try to read in the double.

For example

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

You can write this more tersely as follows

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

If the input fails, the value of Delay1 will not change, and so if you have not previously initialized it, it will be some arbitrary value. As has been pointed out, though, it will not become "NULL", since only pointers can be null, not value-types.

伴梦长久 2024-08-10 07:41:39

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

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

由于 operator>> 始终返回其左侧参数,因此这也有效:

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

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

The way to check if stream input worked is to test the stream:

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

Since operator>>always returns its left argument, this works, too:

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

Input streams will not alter the value if inputting fails. In your case, they will thus keep the random values they had before. You should never accept input without having checked the stream.

花心好男孩 2024-08-10 07:41:39

这里有很多问题。

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

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

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

There's multiple things going wrong here.

First: to check whether parsing failed, use if (cin.fail()) { /* print error */ }.

Second: Delay1 || Delay2 || Delay3 will convert doubles to boolean values, and then logical-OR them together.

Third: == NULL will compare your boolean value (in this case false) to the pointer value NULL. I believe that this will always be true.

春风十里 2024-08-10 07:41:39

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

Your if condition is wrong. if(Delay1 || Delay2 || Delay3 == NULL) will be true if Delay is not equal to zero or delay2 is not equal to zero or Delay3 is zero. Surely that is not what you want. Also you should use 0 for primitive data types. Further, comparing the double values to an absolute value is always dangerous. You check whether the value is less than a small epsilon value.

若能看破又如何 2024-08-10 07:41:39

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

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

just use the stream state, it will be in a fail state if it couldn't read a double.

if(!(std::cin >> Delay1 >> Delay2 >> Delay3)) {
    // error
}
复古式 2024-08-10 07:41:39

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

I think you need to read the variable in as a string, then check to see if it's blank, then convert it to a double (and check if it's a valid double - the user might just have typed "hello").

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文