就像是
cin >> Delay1;
if(cin) { ... }
不会根据您的规范工作,因为cin
会跳过前导空格。用户不能只是按回车键。他首先必须输入一些文字。如果他输入以下
3a
然后输入被读入双精度,直到a
它停止。cin
不会发现有什么不对,a
就在溪流中离开。通常,我认为这是足够的错误处理。但是,如果您希望在用户输入类似上述内容时实际重复,那么您需要更多代码。
如果要测试直到换行符的整个输入是否为数字,则应使用getline
, 读入字符串,然后尝试转换为数字
string delay;
if(!getline(std::cin, delay) || !isnumber(delay)) {
...
}
该isnumber
函数可以使用 stringstream 来测试字符串
bool isnumber(string const &str) {
std::istringstream ss(str);
double d;
// allow leading and trailing whitespace, but no garbage
return (ss >> d) && (ss >> std::ws).eof();
}
将operator>>
吃掉前导空格,std::ws
并将消耗尾随空格。如果它到达流的末尾,它将发出信号eof
。这样,您可以立即向用户发出错误信号,而不是在下次尝试从cin
.
编写一个类似的函数,返回双精度数或将双精度数的地址传递给`isnumber,以便在解析成功的情况下写入结果。
还值得看看各种错误标志以及它们与operator void*
, operator!
, good()
,的关系fail()
,这可能会让人很困惑:bad()
eof()
flag | badbit | failbit | eofbit
function | | |
-----------------+---------+-----------+--------
op void* | x | x |
-----------------+---------+-----------+--------
op ! | x | x |
-----------------+---------+-----------+--------
good() | x | x | x
-----------------+---------+-----------+--------
fail() | x | x |
-----------------+---------+-----------+--------
bad() | x | |
-----------------+---------+-----------+--------
eof() | | | x
-----------------+---------+-----------+--------
x
如果相应的位影响结果,则存在一个。operator void*
转换为bool
(if(cin) ...
)时使用,而operator!
用于代码执行!cin