1

getRegionTotal()是我现在用于验证的功能。它工作得很好,如果用户输入“二十”或 -7 之类的东西,它不会接受它,它会继续要求新值,直到它得到一个有效的值。但是,如果用户输入 60.7 作为北部地区的事故数量,它将接受 60 并删除 0.7 部分。然后它会在询问南部地区的事故数量时给出常规指示和更具体的指示。

//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;
}
4

1 回答 1

1

解析整行并确保您已经使用了整行。

使用 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"
}

使用标准库:

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

这两种方法基本相同,但前者可能更“惯用的 C++”。也就是说,如果您已经有一个现有的字符串,那么strtol- 方法是一个很好的选择,因为它可以为您提供精确的错误处理:您是否使用了整个字符串(如果没有,则e指向下一个字符);您是否使用了任何字符串(如果没有,则e指向开头);是否有溢出或下溢(检查errno)。另一方面, iostreams 方法允许您使用尾随空格(感谢>> std::ws),而strtol-solution 没有。

还有std::stolwhich wraps (对于/等strtol也是类似的),但它会在错误时引发异常,并且我认为异常不是构建正常行为(如读取用户输入)的控制流的正确工具。此外,您无法控制这些包装器的操作方式;例如,即使他们不消耗整个字符串(但不告诉你他们走了多远),也会成功,并且你不能指定数字基数。strtoullstrtod

于 2013-09-24T08:07:19.160 回答