Domanda

Qual è il modo migliore e più sicuro per recuperare un unsigned long da una stringa in C ++?

So di un certo numero di possibili metodi.

In primo luogo, la conversione di un firmato lungo tratto da Atol.

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

Il problema evidente con questo è, che cosa accade quando il valore memorizzato in myStr è più grande di una firma lunga può contenere? Cosa atol recuperare?

La prossima possibilità è quella di utilizzare strtoul.

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

Tuttavia, questo è un po 'più complicato per le mie esigenze. Vorrei una semplice funzione, stringa, unsigned long base 10 fuori. Inoltre, la gestione degli errori lascia molto a desiderare.

L'ultima possibilità che ho trovato è quello di utilizzare sscanf.

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

Anche in questo caso, la gestione degli errori lascia molto a desiderare, e un po 'più complicato di quanto mi piacerebbe.

La soluzione ovvia rimanente è di scrivere il mio sia un involucro intorno una delle possibilità precedenti o qualche cosa che cicli attraverso la stringa e converte manualmente ogni cifra fino a raggiungere ULONG_MAX.

La mia domanda è, quali sono le altre opzioni che il mio google-fu è riuscito a trovare? Qualsiasi cosa in C ++ libreria std che modo pulito di convertire una stringa in un unsigned long e generare eccezioni in caso di fallimento?

Le mie scuse se questa è una vittima, ma non riuscivo a trovare tutte le domande con una corrispondenza esatta la mia.

È stato utile?

Soluzione

Un modo per farlo:

stringstream(str) >> ulongVariable;

Altri suggerimenti

È possibile utilizzare strtoul senza alcun problema. La funzione restituisce un unsigned long. Se la conversione non può essere eseguita la funzione di ritorno 0. Se il valore a lungo corretto è fuori portata del ritorno funzione di ULONG_MAX e la variabile globale errno è impostato su 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);

Se è possibile utilizzare le librerie Boost (www.boost.org) cerca nella libreria di conversione - si tratta di un colpo di testa comprende solo

#include "boost/lexical_cast.hpp"

, allora tutto quello che dovete fare è

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

Jeffrey saldi ha un bellissimo post sulle routine parser scrittura int per Mono (in C).
Esso genera il codice che utilizza utilizza tipi nativi (è necessario a 32 bit per analizzare a 32 bit) e codici di errore per troppo pieno.

Con "Atol" in-built funzione std

Ad esempio di input std :: string = "1024";

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

Atol si aspettano parametro per essere di tipo stringa c, così c_str () lo fa per te.

modo robusto sarà scrivere una funzione statica e utilizzarlo

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

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

}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top