简体   繁体   English

验证整数输入C ++?

[英]validate integer input C++?

I use !(cin >> input) to validate integer input, but it does not catch other datatypes such as floats. 我使用!(cin >> input)来验证整数输入,但它不会捕获其他数据类型,例如浮点数。 Instead it takes the first whole number. 相反,它需要第一个整数。 EG: 例如:

Please enter a number: 2.5. 请输入一个数字:2.5。

My error message appears here, it is suppose to loop round but it takes first number instead. 我的错误信息出现在这里,它假设循环,但它取代第一个数字。

Outputs "2" 输出“2”

How do I get it to ignore decimal input? 如何让它忽略十进制输入?

The input stream considers anything starting with a sign followed by at least one decimal digit to be a valid integer input. 输入流将任何以符号开头,后跟至少一个十进制数的内容视为有效的整数输入。 If you want to fail on a decimal input including a decimal point, you need to do something different. 如果要在包含小数点的十进制输入上失败,则需要执行不同的操作。 One way to deal with this to read an integer and see if the character following the successful read of an integer is a decimal point: 解决此问题的一种方法是读取一个整数并查看成功读取整数后的字符是否为小数点:

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

As Thomas Matthews correctly pointed out, the problem isn't really limited to floating point numbers but anything with a prefix of digits followed by a non-space (and not EOF: the above solution would actually miss a valid integer at the very end of a file, ie, not followed by anything, not even a newline). 正如托马斯马修斯正确指出的那样,问题并不仅限于浮点数,而是任何前缀为数字后跟非空格的东西(而非EOF:上述解决方案实际上会错过最后一个有效整数)一个文件,即没有任何东西,甚至没有换行符。 To only read integers followed by a space or at the end of a file, something like this would be in order: 要仅读取整数后跟空格或文件末尾,这样的内容将按顺序排列:

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

There isn't really any way to return the already read characters. 没有任何方法可以返回已读取的字符。 Since this isn't really nice to be used in many places, it may be reasonable to package this function into a suitable std::num_get<char> facet and imbue() the stream with a corresponding std::locale . 由于在许多地方使用它并不是很好,因此将此函数打包到合适的std::num_get<char> facet并使用相应的std::locale imbue()流可能是合理的。 This is a bit more advanced although the expression to deal with the code is actually simpler. 尽管处理代码的表达式实际上更简单,但这有点高级。

You will need to read the full input before validating it. 在验证之前,您需要阅读完整的输入。 You could use cin.getline() or getline() to do that, then check to see if the input is what you want. 您可以使用cin.getline()getline()来执行此操作,然后检查输入是否是您想要的。

You are trying to read different types of values using cin. 您正尝试使用cin读取不同类型的值。

istream overload the >> operator to match the type of data you are expecting from input, and cin is a instance of the istream class. istream重载>>运算符以匹配您期望输入的数据类型,而cinistream类的实例。

When the expected type is an integer, it will consume character up to a string which can be converted to an integer, and leave the remaining characters in the stream for later parsing. 当期望的类型是整数时,它将消耗字符直到可以转换为整数的字符串,并将剩余的字符留在流中以供稍后解析。 The same happens with a float value, or with other simple types. 浮点值或其他简单类型也会发生同样的情况。 See this reference page for more details on the operator and the types it supports out of the box. 有关操作员及其支持的类型的详细信息,请参阅此参考页 The bottom line is that if you want to have an integer value, but are expecting a float value from input, you must use the correct type of value you want to parse from input (here float), and do any needed conversion later on (here use trunc , floor , ceil or whichever rounding function that match your needs). 最重要的是,如果你想要一个整数值,但是期望输入的浮点值,你必须使用你想要从输入中解析的正确类型的值(这里是float),并在稍后进行任何所需的转换(这里使用truncfloorceil或任何符合您需求的舍入函数)。

Here's a simple example: 这是一个简单的例子:

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

}

This very simple program demonstrate the use of the >> operator on istream, specifically with an expected float value. 这个非常简单的程序演示了在istream上使用>>运算符,特别是预期的浮点值。 For the following input: "1.2345Z6789" (note the Z in the middle of the number), the program will parse the value "1.2345" and have "Z6789" remaining in the input buffer, available for a subsequent read. 对于以下输入:“1.2345Z6789”(注意数字中间的Z ),程序将解析值“1.2345”并在输入缓冲区中保留“Z6789”,可用于后续读取。

If you replace the type of f from float to int , the program, on the same input, would read the value "1", and have ".2345Z6789" remaining in the input buffer. 如果将f的类型从float替换为int ,则在同一输入上的程序将读取值“1”,并在输入缓冲区中保留“.2345Z6789”。

Note: In your code, you are using the ! 注意:在您的代码中,您正在使用! operator to test the state of the stream, which is equivalent to the fail method, which I used in my example. 运算符来测试流的状态,这相当于我在我的例子中使用的fail方法。

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

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