Question

Quelle est la plus sûre et la meilleure façon de récupérer un unsigned long d'une chaîne en C ++?

Je connais un certain nombre de méthodes possibles.

Tout d'abord, la conversion d'un long signé provenant Atol.

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

Le problème évident avec ceci est, ce qui se passe lorsque la valeur stockée dans myStr est plus grand qu'un long signé peut contenir? Qu'est-ce que récupérer Atol?

La possibilité suivante consiste à utiliser strtoul.

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

Cependant, cela est un peu plus compliqué pour mes besoins. Je voudrais une simple fonction, chaîne dans, la base unsigned long sur 10. En outre, le traitement des erreurs laisse beaucoup à désirer.

La dernière possibilité que j'ai trouvé est d'utiliser sscanf.

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

Encore une fois, la gestion des erreurs laisse beaucoup à désirer, et un peu plus compliqué que ce que je voudrais.

L'option évidente restante est d'écrire mon propre soit une enveloppe autour d'une des possibilités précédentes ou quelque chose qui cycles à travers la chaîne et convertit manuellement chaque chiffre jusqu'à ce qu'il atteigne ULONG_MAX.

Ma question est, quelles sont les autres options que mon google-fu n'a pas réussi à trouver? Toute chose dans la bibliothèque C de std qui proprement convertir une chaîne à une longue et jeter non signé exceptions en cas d'échec?

Mes excuses si cela est dupe, mais je ne pouvais pas trouver toutes les questions que correspondant exactement à moi.

Était-ce utile?

La solution

Une façon de le faire:

stringstream(str) >> ulongVariable;

Autres conseils

Vous pouvez utiliser strtoul sans problème. La fonction retourne un unsigned long. Si convertion ne peut pas être effectué le retour de la fonction 0. Si la valeur à long correcte est hors de portée du retour de la fonction ULONG_MAX et la variable globale errno 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 vous pouvez utiliser les bibliothèques Boost (www.boost.org) regardez la bibliothèque de conversion - c'est un en-tête comprend seulement

#include "boost/lexical_cast.hpp"

tout ce que vous devez faire est de

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

Jeffrey Stedfast a une belle post sur les routines d'écriture analyseur int Mono (en C).
Il génère un code qui utilise utilise des types natifs (vous avez besoin de 32 bits pour analyser 32 bits) et les codes d'erreur pour dépassement.

Utilisez "Atol" en fonction intégrée std

Par exemple std :: entrée de chaîne = "1024";

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

Atol attendre paramètre à être une chaîne de type c, donc c_str () il le fait pour vous.

façon robuste sera écrire une fonction statique et de l'utiliser

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

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

}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top