getRegionTotal()
是我现在用于验证的功能。它的工作原理非常好,如果用户输入类似“二十”或-7的内容,它将不会接受它,并且它将继续询问新值,直到它获得有效值。但是,如果用户输入60.7的北部地区的事故数量,它将接受60并丢弃.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;
}
答案 0 :(得分:1)
解析整条线并确保你消耗了整条线。
使用iostreams:
#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"
}
使用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
}
这两种方法基本相同,但前者可能更“惯用C ++”。也就是说,如果你已经有了一个现有的字符串,strtol
- 方法是一个很好的选择,因为它可以为你提供精确的错误处理:你是否消耗了整个字符串(如果没有,e
指向下一个字符);你是否消费字符串的任何(如果没有,e
指向开头);有溢出或下溢(检查errno
)。另一方面,iostreams方法允许您使用尾随空格(感谢>> std::ws
),strtol
- 解决方案没有。
还有std::stol
包裹strtol
(类似于strtoull
/ strtod
等),但它会在错误时抛出异常,我相信异常是不是用于构造正常行为的控制流的正确工具,例如读取用户输入。此外,您无法控制这些包装器的运行方式;例如,即使他们不消耗整个字符串也会成功(但不告诉你他们得到了多少),并且你不能指定数字基数。