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)
объяснение переменной «мусора»:
почему бы просто не проверить, есть ли у извлечения в моем double правильное значение, а затем вернуть true, если оно есть?
Обратите внимание, пример 3 выше все равно будет успешно считывать число 11 в переменную my_number, даже если входная строка - "11ABCD" (которая не является числом).
для обработки этогоВ этом случае мы можем выполнить другое извлечение в строковую переменную (которую я назвал мусором), которая может прочитать все, что могло остаться в строковом буфере после первоначального извлечения в переменную.типа двойной.Если что-то осталось, оно будет считано «мусором», что означает, что переданная полная строка не была числом (она просто начинается с единицы).в этом случае мы бы хотели вернуть false;
объяснение с добавлением "0":
попытка извлечь один символ в двойку не удастся (возвращая 0 в наш double), но все равно будет перемещать позицию строкового буфера после символа. В этом случае наше чтение мусора будет пустым, что приведет к неправильному возвращению функции true. Чтобы обойти это, я добавил к строке 0, так чточто, например, если переданная строка была "a", она заменяется на "0a", так что 0 будет извлечен в двойное число, а "a" извлечено в мусор.
добавление 0 не повлияетзначение числа, так что число все равно будет правильно извлечено в нашу двойную переменную.