Pregunta

¿Cuál es la forma más segura y mejor para recuperar un largo sin signo de una cadena en C ++?

No conozco una serie de posibles métodos.

En primer lugar, la conversión de una larga firmado tomado de atol.

char *myStr; // Initalized to some value somehow.
unsigned long n = ((unsigned)atol(myStr));

El problema obvio con esto es, lo que sucede cuando el valor almacenado en myStr es más grande que una larga firmado puede contener? ¿Qué recuperar atol?

La siguiente posibilidad es utilizar strtoul.

char *myStr; // Initalized to some value somehow.
unsigned long n = strtoul(myStr, 0, 10);

Sin embargo, esto es un poco más complicado para mis necesidades. Me gustaría tener una función simple, cadena en, sin signo de 10 bases de longitud a cabo. Además, el manejo de errores deja mucho que desear.

La última posibilidad que he encontrado es utilizar sscanf.

char *myStr; // Initalized to some value somehow.
unsigned long n = 0;
if(sscanf(myStr, "%lu", n) != 1) {
    //do some error handling
}

Una vez más, el manejo de errores deja mucho que desear, y un poco más complicado de lo que me gustaría.

La opción obvia restante es escribir mi propia o bien una envoltura alrededor de una de las posibilidades anteriores o alguna cosa que cicla a través de la cadena y la convierte manualmente cada dígito hasta que llega ULONG_MAX.

Mi pregunta es, ¿cuáles son las otras opciones que mi google-fu fallidos ha de encontrar? Cualquier cosa en la biblioteca de C ++ std que convertirá limpiamente una cadena en un tiempo sin firmar y lanzar excepciones en caso de fallo?

Mis disculpas si esto es una víctima, pero no pudo encontrar las preguntas que han coincidido exactamente con la mía.

¿Fue útil?

Solución

Una forma de hacerlo:

stringstream(str) >> ulongVariable;

Otros consejos

Puede utilizar strtoul sin ningún problema. La función devuelve un largo sin signo. Si la conversión no se puede realizar la función de retorno 0. Si el valor a largo correcta está fuera del alcance del retorno de la función ULONG_MAX y la variable global errno tomará ERANGE.

template <class T>
T strToNum(const std::string &inputString,
           std::ios_base &(*f)(std::ios_base&) = std::dec)
{
    T t;
    std::istringstream stringStream(inputString);

    if ((stringStream >> f >> t).fail())
    {
        throw runtime_error("Invalid conversion");
    }
    return t;
}


// Example usage
unsigned long ulongValue = strToNum<unsigned long>(strValue);
int intValue             = strToNum<int>(strValue);

int intValueFromHex      = strToNum<int>(strHexValue,std::hex);
unsigned long ulOctValue = strToNum<unsigned long>(strOctVal, std::oct);

Si usted puede utilizar las bibliotecas Boost (www.boost.org) mira el biblioteca de conversión - es una cabecera sólo incluyen

#include "boost/lexical_cast.hpp"

entonces todo lo que necesita hacer es

unsigned long ul = boost::lexical_cast<unsigned long>(str);

Jeffrey firme tiene un puesto hermosa sobre las rutinas del analizador de escritura int para Mono (en C).
Genera código que utiliza utiliza tipos nativos (que necesitan 32 bits para analizar 32 bits) y códigos de error de desbordamiento.

Utilice "atol" incorporada la función std

Para la entrada de ejemplo std :: string = "1024";

std :: atol (input.c_str ());

Atol esperar parámetro a ser de tipo secuencia de c, por lo c_str () lo hace por usted.

manera robusta será escribir una función estática y utilizarlo

bool str2Ulong(const string& str,unsigned long & arValue)
{
   char *tempptr=NULL;
   arValue=strtoul(str,tempptr,10);

   return ! (arValue==0 && tempptr==str.c_str());

}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top