8

我在http://www.parashift.com/c++-faq-lite/istream-and-ignore.html找到了这个链接

它显示“如何让 std::cin 跳过无效的输入字符?”

Use std::cin.clear() and std::cin.ignore().

#include <iostream>
#include <limits>

int main()
{
  int age = 0;

  while ((std::cout << "How old are you? ")
         && !(std::cin >> age)) {
    std::cout << "That's not a number; ";
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
  }

  std::cout << "You are " << age << " years old\n";
  ...
}
Of course you can also print the error message when the input is out of range. For example, if you wanted the age to be between 1 and 200, you could change the while loop to:
  ...
  while ((std::cout << "How old are you? ")
         && (!(std::cin >> age) || age < 1 || age > 200)) {
    std::cout << "That's not a number between 1 and 200; ";
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
  }
  ...
Here's a sample run:
How old are you? foo
That's not a number between 1 and 200; How old are you? bar
That's not a number between 1 and 200; How old are you? -3
That's not a number between 1 and 200; How old are you? 0
That's not a number between 1 and 200; How old are you? 201
That's not a number between 1 and 200; How old are you? 2
You are 2 years old

我无法了解它是如何做到的 > 谁能解释一下吗?

我有疑问:

while ((std::cout << "How old are you? ")
             && !(std::cin >> age)) 

它如何检查有效条目?我的意思是问表达式 "std::cout << "How old are you?" 和 "!(std::cin >> age)" ,返回真或假,哪些是与运算?

另一件令人困惑的事情是用法,

std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

有什么目的?在谷歌上搜索了这些功能,但我仍然不清楚。特别,std::numeric_limits<std::streamsize>::max()

任何人都可以帮忙吗?谢谢

4

3 回答 3

10

插入和提取运算符<<以及>>on 流将返回对流本身的引用。这就是为什么你可以像这样将插入串在一起:

std::cout << "Hello, " << "World!";

首先std::cout << "Hello, "返回对的引用std::cout,然后你有std::cout << "World!".

流也可以转换为bool. 这基本上检查流的状态是否仍然正常。什么都没有失败。例如,您可以这样做:

if (std::cin) // ...

这将检查std::cin流是否仍处于良好状态。

现在让我们看一下您询问的代码:

while ((std::cout << "How old are you? ")
         && !(std::cin >> age))

插入std::cout不会导致失败。它包含在这里的唯一原因是它每次都在输入到age. 另一种方法是将它放在身体的前面while和身体的末端while

插入std::cout完成后,!(std::cin >> age)将进行评估。这将首先让用户提供一个age. 然后可能会发生两件事:

  1. 如果这以某种方式失败(可能用户输入字符而不是整数),则将设置失败位。这意味着 will 的结果std::cin >> age将转换为 a boolwhich will be false。会将其!反转为true. 所以因为第一个和第二个条件都为真,while循环体将执行,告诉用户他们输入了一个无效值,循环将再次循环。

  2. 如果输入成功, 的结果std::cin >> age将为true并将!其转为false。这意味着while循环体不会执行,也不会告诉用户他们输入了错误的值。

现在让我们看看:

std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

这仅在上述情况 1 中发生,即输入失败。如果流进入失败状态,则在清除状态之前,它将不再接受任何插入或提取。就是clear()这样。然后调用ignore说提取所有字符,包括\n流中的下一个字符并丢弃它们。这消除了流中的无效输入。

于 2013-04-26T10:37:24.757 回答
1
while ((std::cout << "How old are you? ")        && !(std::cin >> age)) 

cout是类的全局对象,是类ostreamcin全局对象istream

这些对象与重载运算符<<(定义在ostream)和>>(定义在istream)一起使用以获取输入(通过调用为这些运算符定义的函数)

is的返回类型operator<<是 typeostream&operator>>is的返回类型istream&。然后将它们转换为布尔值。看到这个

检查这个cin.ignore()_cin.clear()

于 2013-04-26T10:41:35.477 回答
0

std::numeric_limits允许您获得可以适合给定类型的最大数量。

在您的示例中,它被传递给ignore()函数,这基本上意味着预先忽略每个换行符。

于 2013-04-26T10:35:02.670 回答