isdigit data c++ string floating-point

data - c++ primitive types size



FunciĆ³n C++ IsFloat (12)

Me imagino que querrías ejecutar una coincidencia de expresiones regulares en la cadena de entrada. Creo que puede ser bastante complicado probar todos los casos extremos.

Este sitio tiene buena información sobre él. Si solo quiere saltear hasta el final, dice: ^[-+]?[0-9]*/.?[0-9]+([eE][-+]?[0-9]+)?$

Lo cual básicamente tiene sentido si comprendes la sintaxis regex.

¿Alguien sabe de un medio conveniente para determinar si un valor de cadena "califica" como un número de coma flotante?

bool IsFloat( string MyString ) { ... etc ... return ... // true if float; false otherwise }


Es posible que le guste la versión lexical_cast de Boost (consulte http://www.boost.org/doc/libs/1_37_0/libs/conversion/lexical_cast.htm ).

bool isFloat(std::string someString) { using boost::lexical_cast; using boost::bad_lexical_cast; try { boost::lexical_cast<float>(someString); } catch (bad_lexical_cast &) { return false; } return true; }

Puede usar istream para evitar la necesidad de Boost, pero francamente, Boost es demasiado bueno como para dejar de lado.


Lo que podría hacer es usar un istringstream y devolver verdadero / falso en función del resultado de la operación de transmisión. Algo así (advertencia: ni siquiera he compilado el código, solo es una guía):

float potential_float_value; std::istringstream could_be_a_float(MyString) could_be_a_float >> potential_float_value; return could_be_a_float.fail() ? false : true;


Podría usar atof y luego tener un manejo especial para 0.0 , pero no creo que eso cuente como una solución particularmente buena.


Si no puede usar una función de biblioteca Boost, puede escribir su propia función isFloat de esta manera.

#include <string> #include <sstream> bool isFloat( string myString ) { std::istringstream iss(myString); float f; iss >> noskipws >> f; // noskipws considers leading whitespace invalid // Check the entire string was consumed and if either failbit or badbit is set return iss.eof() && !iss.fail(); }


depende del nivel de confianza que necesita y de dónde provienen los datos de entrada. Si los datos provienen de un usuario, debe ser más cuidadoso, en comparación con los datos importados de la tabla, donde ya sabe que todos los elementos son enteros o flotantes y solo eso es lo que necesita diferenciar.

Por ejemplo, una de las versiones más rápidas, simplemente verificaría la presencia de "." y "eE" en él. Pero luego, es posible que desee ver si el resto es de todos los dígitos. Omita espacios en blanco al principio, pero no en el medio, busque un solo "." "eE" etc.

Por lo tanto, el ayuno rápido de q & d probablemente dará lugar a un enfoque más sofisticado de tipo regEx (llámalo o escánelo tú mismo). Pero entonces, ¿cómo sabe usted que el resultado, aunque parezca una flotación, realmente puede representarse en su máquina (es decir, intente con 1.2345678901234567890e1234567890). Por supuesto, puede hacer un regEx con dígitos "up-to-N" en mantisa / exponente, pero esa máquina / OS / compilador o lo que sea específico, a veces.

Por lo tanto, al final, para estar seguro, es probable que deba solicitar la conversión del sistema subyacente y ver qué obtiene (excepción, infinito o NAN).


[EDITAR: solucionado para prohibir el espacio en blanco inicial y las tonterías finales.]

#include <sstream> bool isFloat(string s) { istringstream iss(s); float dummy; iss >> noskipws >> dummy; return iss && iss.eof(); // Result converted to bool }

Puede convertir fácilmente esto en una función con plantilla en un tipo T lugar de float . Esto es esencialmente lo que hace la emisión lexical de Boost.


Me sentiría tentado a ignorar los espacios en blanco principales, ya que eso es lo que hace la función atof también:

La función primero descarta tantos espacios en blanco como sea necesario hasta que se encuentre el primer carácter que no sea de espacio en blanco. A continuación, a partir de este carácter, se tomarán la mayor cantidad de caracteres que sean válidos siguiendo una sintaxis similar a la de los literales de punto flotante, y se interpretarán como un valor numérico. El resto de la cadena después del último carácter válido se ignora y no tiene ningún efecto sobre el comportamiento de esta función.

Entonces, para hacer coincidir esto, nosotros:

bool isFloat(string s) { istringstream iss(s); float dummy; iss >> skipws >> dummy; return (iss && iss.eof() ); // Result converted to bool }


Esta es una pregunta común sobre SO. Mire esta pregunta para sugerencias (esa pregunta discute string-> int, pero los enfoques son los mismos).

Nota: para saber si la cadena se puede convertir, básicamente debe hacer la conversión para verificar si hay más / menos flujo.


Inspirado por esta respuesta modifiqué la función para verificar si una cadena es un número de coma flotante. No requerirá impulso y no se basa en el flujo de fallas de las cadenas de caracteres; simplemente se trata de un análisis sintáctico.

static bool isFloatNumber(const std::string& string){ std::string::const_iterator it = string.begin(); bool decimalPoint = false; int minSize = 0; if(string.size()>0 && (string[0] == ''-'' || string[0] == ''+'')){ it++; minSize++; } while(it != string.end()){ if(*it == ''.''){ if(!decimalPoint) decimalPoint = true; else break; }else if(!std::isdigit(*it) && ((*it!=''f'') || it+1 != string.end() || !decimalPoint)){ break; } ++it; } return string.size()>minSize && it == string.end(); }

Es decir

1 2. 3.10000 4.2f -5.3f +6.2f

es reconocido por esta función correctamente como flotante.

1.0.0 2f 2.0f1

Son ejemplos de flotantes no válidos. Si no desea reconocer los números de coma flotante en el formato X.XXf, simplemente elimine la condición:

&& ((*it!=''f'') || it+1 != string.end() || !decimalPoint)

de la línea 9. Y si no quieres reconocer los números sin ''.'' como flotante (es decir, no ''1'', solo ''1.'', ''1.0'', ''1.0f'' ...) entonces puedes cambiar la última línea a:

return string.size()>minSize && it == string.end() && decimalPoint;

Sin embargo: hay muchas buenas razones para usar ya sea boost-lexical_cast o la solución que utiliza stringstreams en lugar de esta "fea función". Pero me da más control sobre qué tipo de formatos exactamente quiero reconocer como números de coma flotante (es decir, dígitos máximos después del punto decimal ...).



Solución C ++ 11 usando std::stof :

bool isFloat(const std::string& s) { try { std::stof(s); return true; } catch(...) { return false; } }