3

!(cin >> input)用来验证整数输入,但它不捕获其他数据类型,例如浮点数。相反,它需要第一个整数。例如:

请输入一个数字:2.5。

我的错误消息出现在这里,假设循环,但它需要第一个数字。

输出“2”

如何让它忽略十进制输入?

4

3 回答 3

1

输入流将任何以符号开头后跟至少一个十进制数字的内容视为有效的整数输入。如果您想在包含小数点的十进制输入上失败,您需要做一些不同的事情。处理此问题的一种方法是读取整数并查看成功读取整数之后的字符是否为小数点:

if (!(std::cin >> value)
    || std::cin.peek() == std::char_traits<char>::to_int_type('.')) {
    deal_with_invalid_input(std::cin);
}

正如 Thomas Matthews 正确指出的那样,问题并不仅限于浮点数,而是任何带有数字前缀后跟非空格的东西(而不是 EOF:上述解决方案实际上会在末尾丢失一个有效整数一个文件,即后面没有任何东西,甚至没有换行符)。要仅读取后跟空格或文件末尾的整数,如下所示:

if (!(std:cin >> value)
    || (!std::isspace(std::cin.peek())
        && std::cin.peek() != std::char_traits<char>::eof())) {
    deal_with_invalid_input(std::cin);
}

实际上没有任何方法可以返回已读取的字符。由于这在很多地方都不是很好用,因此将这个函数打包成一个合适的std::num_get<char>facet 和imbue()对应的流可能是合理的std::locale。尽管处理代码的表达式实际上更简单,但这有点高级。

于 2012-11-13T22:50:30.497 回答
0

您正在尝试使用 cin 读取不同类型的值。

istream重载>>运算符以匹配您期望从输入中获得的数据类型,并且cinistream该类的一个实例。

当期望的类型是整数时,它将消耗字符到一个可以转换为整数的字符串,并将剩余的字符留在流中以供以后解析。浮点值或其他简单类型也会发生同样的情况。有关运算符及其开箱即用支持的类型的更多详细信息,请参阅此参考页面。底线是,如果您想要一个整数值,但期望输入的浮点值,您必须使用要从输入解析的正确类型的值(此处为浮点),并在稍后进行任何需要的转换(此处使用trunc,floorceil任何符合您需要的舍入函数)。

这是一个简单的例子:

#include <iostream>
#include <string>

using namespace std;

int main() {

    float f;
    string str;

    cout << "please enter a float :";
    cin >> f;

    cout << "value entered : " << f << endl;

    cout << "stream error : " 
         << (cin.fail() ? "yes" : "no") 
         << endl;

    cin >> str;

    cout << "remaining data : " << str << endl;

}

这个非常简单的程序演示了>>istream 上运算符的使用,特别是预期的浮点值。对于以下输入:“1.2345Z6789”(注意数字中间的Z),程序将解析值“1.2345”并将“Z6789”保留在输入缓冲区中,以供后续读取。

如果您替换ffrom floatto的类型int,则程序在同一输入上将读取值“1”,并在输入缓冲区中保留“.2345Z6789”。

注意:在您的代码中,您使用!运算符来测试流的状态,这相当于fail我在示例中使用的方法。

于 2012-11-13T23:36:03.433 回答
0

您需要在验证之前阅读完整的输入。您可以使用cin.getline()orgetline()来执行此操作,然后检查输入是否是您想要的。

于 2012-11-13T22:50:03.697 回答