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 >> может преобразовывать строки в различные арифметические типы, она делает это, последовательно считывая символы из потока строк (в данном случае ss), пока в нем не закончатся символы ИЛИ следующий символ не соответствует критериям для сохранения в тип целевой переменной.
example1:
stringstream ss("11");
double my_number;
ss >> my_number; //my number = 11
example2:
stringstream ss("011");
double my_number;
ss >> my_number; //my number = 11
example3:
stringstream ss("11ABCD");
double my_number;
ss >> my_number; //my number = 11 (even though there are letters after the 11)
объяснение "мусорной" переменной ":
почему бы просто не проверить, имеет ли извлечение в мой двойник допустимое значение, а затем вернуть истину, если это так?
обратите внимание, что example3 выше по-прежнему успешно считывает число 11 в переменную my_number, даже если входная строка - «11ABCD» (которая не является числом).
для обработки этого случая мы можем выполнить другое извлечение в строковую переменную (которую я назвал мусором), которая может прочитать все, что могло остаться в строковом буфере после первоначального извлечения в переменную типа double. Если что-то останется, это будет прочитано в «мусор», что означает, что переданная полная строка не была числом (она просто начинается с единицы). в этом случае мы хотели бы вернуть false;
добавленное «0» объяснение:
попытка извлечь одиночный символ в двойной потерпит неудачу (возврат 0 в наш двойной), но все равно будет перемещать позицию строкового буфера после символа. В этом случае чтение мусора будет пустым, что приведет к неправильному возврату функции true. чтобы обойти это, я добавил к строке 0, так что если, например, переданная строка была «a», она изменилась на «0a», так что 0 будет извлечен в двойное, а «a» извлечено в мусор.
добавление 0 не повлияет на значение числа, поэтому число по-прежнему будет правильно извлечено в нашу двойную переменную.
if (expr) return true; return false;
! Просто напишитеreturn expr;
.