简体   繁体   English

C ++如何检查输入浮点变量是否有效

[英]C++ How to check an input float variable for valid input

I'm writing a program that acts as a calculator; 我正在编写一个充当计算器的程序; based on the character input by the user it performs a certain operation. 基于用户输入的字符,它执行特定操作。 The structure of the program seems to work fine, but I'd like to be able to check for erroneous input. 该程序的结构似乎工作正常,但我希望能够检查错误的输入。 After receiving the float variable, is there any way to check if it does not contain any characters other than digits and decimals? 收到float变量后,有没有办法检查它是否包含除数字和小数以外的任何字符? I've tried isdigit , and this: 我尝试过isdigit ,这︰

if (!(cin >> x)) {
    cout << "You did not enter a correct number!" << endl; 
    return;
}

But nothing seems to be working. 但似乎没有任何效果。

Here is a sample of one of the simple operation functions I'm using: 以下是我正在使用的一个简单操作函数的示例:

void Add(){
    float x = 0, y = 0, z = 0;
    cout << "Please enter two numbers you wish "
         << "to add separated by a white space:" << endl; 
    cin >> x >> y;
    z = x+y;
    cout << x << " + " << y << " = " << z << "." << endl;
    return;
}

You test the state of the stream: 您测试流的状态:

float x, y;
if (std::cin >> x >> y) {
    // input extraction succeeded
}
else {
    // input extraction failed
}

If this isn't working for you, then you need to post the exact code that isn't working. 如果这对您不起作用,那么您需要发布不起作用的确切代码。

To detect erroneous string input where you expected a number, C++ doesn't automatically know what you want, so one solution is to first accept your input as strings, validate those strings, then if valid, only then convert the strings to float numbers using the atof() function. 为了在期望数字的位置检测到错误的字符串输入,C ++不会自动知道您想要的是什么,因此一种解决方案是首先将输入作为字符串接受,验证这些字符串,然后验证(如果有效),然后使用atof()函数。

The standard string class has a function called find_first_not_of() to help you tell C++ which characters you consider valid. 标准字符串类有一个名为find_first_not_of()的函数,可以帮助您告诉C ++您认为哪些字符有效。 If the function finds a character not in your list, it will return the position of the bad character, otherwise string::npos is returned. 如果函数找到不在列表中的字符,它将返回错误字符的位置,否则返回string :: npos。

// add.cpp

#include <iostream>
#include <string>
#include <cstdlib>    // for atof()

using namespace std;


void Add()
{
    cout << "Please enter two numbers you wish "
         << "to add, separated by a white space:"
         << endl;

    string num1, num2;

    cin >> num1;
    if( num1.find_first_not_of("1234567890.-") != string::npos )
    {
        cout << "invalid number: " << num1 << endl;
        return;
    }

    cin >> num2;
    if( num2.find_first_not_of("1234567890.-") != string::npos )
    {
        cout << "invalid number: " << num2 << endl;
        return;
    }

    float x = 0, y = 0, z = 0;
    x = atof( num1.c_str() );
    y = atof( num2.c_str() );
    z = x+y;

    cout << x << " + " << y << " = " << z << "." << endl;
}

int main(void)
{
    Add();
    return 0;
}

One possibility would be to read the input as a string, then use boost lexical_cast to convert to floating point. 一种可能性是将输入作为字符串读取,然后使用boost lexical_cast转换为浮点。 lexical_cast only considers the conversion successful if the entire input converts to the target -- otherwise, it'll throw a bad_lexical_cast exception. 如果整个输入转换为目标,则lexical_cast仅认为转换成功 - 否则,它将抛出bad_lexical_cast异常。

Another idea would be to test the input against a regex. 另一个想法是针对正则表达式测试输入。 An example regex for a float could be 浮点数的正则表达式示例可能是

-?[0-9]+([.][0-9]+)?

This method would also make it easier to refine the matching mechanism by only modifying the regex, and you could map multiple regular expressions against different types of input, for example an integer could then be expressed as 通过仅修改正则表达式,此方法还可以更轻松地改善匹配机制,并且可以针对不同类型的输入映射多个正则表达式,例如,可以将整数表示为

-?[0-9]+

and so on. 等等。 Keep in mind however, that this only tests if the input is a valid format, it still requires a numerical conversion afterwards (I prefer boost::lexical_cast). 但请记住,这仅测试输入是否为有效格式,之后仍然需要进行数值转换(我更喜欢boost :: lexical_cast)。

(You can also try it out with http://gskinner.com/RegExr/ ) (您也可以通过http://gskinner.com/RegExr/尝试一下)

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

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