简体   繁体   English

如何制作不接受浮点值的整数验证函数?

[英]How to make an integer validation function that does not accept floating point values?

getRegionTotal() is the function I'm using for validation right now. getRegionTotal()是我现在用于验证的函数。 It works pretty well in that if the user enters something like "twenty" or -7, it will not accept that and it will keep asking for new values until it gets one that is valid. 它的工作原理非常好,因为如果用户输入“二十”或“ -7”之类的东西,它将不会接受,并且会一直要求新值,直到获得有效的值为止。 However if the user enters 60.7 for the number of accidents in the north region, it will accept 60 and drop the .7 part. 但是,如果用户为北部地区的事故数量输入60.7,它将接受60并删除.7部分。 Then it will give both the regular instructions and the more specific instructions when it asks for the number of accidents in the south region. 然后,当询问南部地区的事故数量时,它将提供常规说明和更具体的说明。

//These will hold the number of accidents in each region last year
int northTotal = 0;
int southTotal = 0;
int eastTotal = 0;
int westTotal = 0;
int centralTotal = 0;

//passing 0 for northTotal, southTotal etc. because main doesn't know
//values of them until the function returns a value. When it returns a value
//it will go into the variables on the left. getRegionTotal will get the number
//of accidents for a region from the user and prompt the user using the string that
//is in the first argument.
northTotal = getRegionTotal("North", northTotal);
southTotal = getRegionTotal("South", southTotal);
eastTotal = getRegionTotal("East", eastTotal);
westTotal = getRegionTotal("West", westTotal);
centralTotal = getRegionTotal("Central", centralTotal);


int getRegionTotal(string regionName, int regionTotal)
{
    //instructs user to enter number of accidents reported in a particular region
    cout << "\nNumber of automobile accidents reported in " << regionName << " " << cityName << ": ";
    //while regionTotal is not an integer or regionTotal is negative
    while (!(cin >> regionTotal) || (regionTotal < 0) )
    {
        //give user more specific instructions
        cout << "\nPlease enter a positive whole number for the number of\n";
        cout << "automobile accidents in " << regionName << " " << cityName << ": ";
        cin.clear(); //clear out cin object
        cin.ignore(100, '\n'); //ignore whatever is in the cin object
                                //up to 100 characters or until
                                // a new line character
    }
    //returns a valid value for the number of accidents for the region
    return regionTotal;
}

Parse the whole line and make sure you've consumed the whole line. 解析整行,并确保您已消耗整行。

With iostreams: 使用iostream:

#include <iostream>
#include <sstream>
#include <string>

for (std::string line; std::getline(std::cin, line); )
{
    std::istringstream iss(line);
    int result;

    if (!(iss >> result >> std::ws && iss.get() == EOF))
    {
        // error, die. For example:

        std::cout << "Unparsable input: '" << line << "'\n";
        continue;
    }

    // else use "result"
}

With stdlib: 使用stdlib:

#include <errno>
#include <cstdlib>

char const * input = line.c_str();   // from above, say
char * e;
errno = 0;

long int result = std::strtol(input, &e, 10);

if (e == input || *e != '\0' || errno != 0)
{
    // error
}

The two approaches are fundamentally identical, but the former may be more "idiomatic C++". 两种方法在根本上是相同的,但前一种可能更像是“惯用的C ++”。 That said, if you already have an existing string, the strtol -approach is a neat alternative, since it gives you precise error handling: did you consume the whole string (if not, e points to the next character); 就是说,如果您已经有一个字符串,则strtol -approach是一个很好的选择,因为它可以为您提供精确的错误处理:是否消耗了整个字符串(如果没有,则e指向下一个字符); did you consume any of the string (if not, e points to the beginning); 您是否消耗了任何字符串(如果没有,则e指向开头); was there an overflow or underflow (check errno ). 是否有上溢或下溢(检查errno )。 On the other hand, the iostreams approach lets you consume trailing whitespace (thanks to >> std::ws ), which the strtol -solution doesn't. 另一方面,iostreams方法使您可以使用结尾的空格(由于>> std::ws ),而strtol -solution则不会。

There's also std::stol which wraps strtol (and similarly for strtoull / strtod etc.), but it throws an exception on error, and I believe that exceptions are not the right tool for structuring control flow of normal behaviour like reading user input. 还有std::stol ,它包装了strtol (和类似的strtoull / strtod等),但是它在出错时引发了异常,我相信异常不是构造正常行为(如读取用户输入)的控制流的正确工具。 Also, you cannot control how those wrappers operates; 而且,您无法控制这些包装程序的运行方式; for example, the succeed even if they don't consume the entire string (but don't tell you how far they got), and you cannot specify the number base. 例如,即使他们不使用整个字符串(但不告诉您他们走了多远),也可以成功,并且您无法指定数字基数。

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

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