bool isNumeric(string s){
if ( !s.empty() && s[0] != '-' )
s = "0" + s; //prepend 0
string garbage;
stringstream ss(s);
ss >> *(auto_ptr<double>(new double)) >> garbage;
/*
//the line above extracts the number into an anonymous variable. it could also be done like this:
double x;
ss >> x >> garbage;
*/
//if there is no garbage return true or else return false
return garbage.empty();
}
工作原理:
stringstream >>重载可以将字符串转换为各种算术类型,方法是从stringstream中顺序读取字符(在这种情况下为ss),直到用完字符,或者下一个字符不符合存储条件转换为目标变量类型。
范例1:
stringstream ss("11");
double my_number;
ss >> my_number; //my number = 11
示例2:
stringstream ss("011");
double my_number;
ss >> my_number; //my number = 11
示例3:
stringstream ss("11ABCD");
double my_number;
ss >> my_number; //my number = 11 (even though there are letters after the 11)
“垃圾”变量说明”:
为什么不只检查提取到我的double中的值是否有效,然后返回true呢?
请注意,即使输入字符串为“ 11ABCD”(非数字),上述example3仍将成功将数字11读取到my_number变量中。
为了处理这种情况,我们可以对字符串变量(我称为垃圾)进行另一次提取,该变量可以读取最初提取为double类型的变量后可能保留在字符串缓冲区中的任何内容。如果剩下任何东西,它将被读为“垃圾”,这意味着传入的完整字符串不是数字(它只是以1开头)。在这种情况下,我们要返回false;
前面的“ 0”说明”:
尝试将单个字符提取为双精度字会失败(将0转换为双精度字),但仍会将字符串缓冲区位置移到该字符之后。在这种情况下,我们的垃圾读取将为空,这将导致函数错误地返回true。为了解决这个问题,我在字符串的前面加上了0,这样,例如,如果传入的字符串是“ a”,则将其更改为“ 0a”,以便将0提取为双精度型,而将“ a”提取为垃圾级。
前置0不会影响数字的值,因此该数字仍将正确提取到我们的double变量中。
if (expr) return true; return false;
!只是写return expr;
。