2010-05-09 20 views
33

Ho bisogno di ottenere un argomento e convertirlo in un int. Ecco il mio codice finora:Come convertire un argomento da riga di comando in int?

#include <iostream> 


using namespace std; 
int main(int argc,int argvx[]) { 
    int i=1; 
    int answer = 23; 
    int temp; 

    // decode arguments 
    if(argc < 2) { 
     printf("You must provide at least one argument\n"); 
     exit(0); 
    } 

    // Convert it to an int here 

} 

risposta

59

Poiché questa risposta è stata in qualche modo accettata e quindi apparirà in alto, sebbene non sia la migliore, l'ho migliorata in base alle altre risposte e ai commenti.

C way; più semplice, ma sarà trattare qualsiasi numero valido come 0:

#include <cstdlib> 

int x = atoi(argv[1]); 

Il modo C con controllo di ingresso:

#include <cstdlib> 

char *endptr; 
long int x = strtol(argv[1], &endptr, 10); 
if (!*argv[1] || *endptr) 
    cerr << "Invalid number " << argv[1] << '\n'; 

Il modo C++ con il controllo di ingresso:

#include <sstream> 

istringstream ss(argv[1]); 
int x; 
if (!(ss >> x)) 
    cerr << "Invalid number " << argv[1] << '\n'; 

Tutte e tre le varianti assumono quello argc >= 2.

+2

Mi consiglia contro atoi: "La funzione atoi() è stata deprecata da strtol() e non deve essere usato in nuovo codice." – WhirlWind

+8

Che dire del fatto che è impossibile stabilire se una conversione sia effettivamente avvenuta con 'atoi'? Questo sembrerebbe un buon motivo per evitare "atoi" per me. –

+2

@WhirlWind Deprecato da chi? –

1

Dai un'occhiata a strtol(), se stai usando la libreria C standard.

18

Si noti che gli argomenti main non sono corretti. La forma standard dovrebbe essere:

int main(int argc, char *argv[]) 

o equivalentemente:

int main(int argc, char **argv) 

Ci sono molti modi per raggiungere la conversione. Questo è un approccio:

#include <sstream> 

int main(int argc, char *argv[]) 
{ 
    if (argc >= 2) 
    { 
     std::istringstream iss(argv[1]); 
     int val; 

     if (iss >> val) 
     { 
      // Conversion successful 
     } 
    } 

    return 0; 
} 
+0

Oh opps è stato un mio errore. Inizialmente l'avevo fatto in quel modo ma poi ho iniziato a provare cose diverse e ho dimenticato di cambiarlo. – nosedive25

+0

+1 per l'inserimento in caso di esito positivo –

+0

ottimo e pulito =) – marcelosalloum

3

Come vortice ha fatto notare, le raccomandazioni per usare atoi non sono davvero molto buona. atoi non ha modo di indicare un errore, quindi si ottiene lo stesso risultato da atoi("0"); come da atoi("abc");. Il primo è chiaramente significativo, ma il secondo è un chiaro errore.

Ha anche raccomandato strtol, che è perfettamente soddisfacente, anche se un po 'goffo. Un'altra possibilità sarebbe quella di utilizzare sscanf, qualcosa di simile:

if (1==sscanf(argv[1], "%d", &temp)) 
    // successful conversion 
else 
    // couldn't convert input 

nota che strtol dà risultati leggermente più dettagliati anche se - in particolare, se hai un argomento come 123abc, la chiamata sscanf sarebbe semplicemente dire che si era convertita un numero (123), mentre strtol non solo ti comunicava che aveva convertito il numero, ma anche un puntatore allo a (cioè, l'inizio della parte che poteva non convertire in un numero).

Poiché si utilizza C++, si potrebbe anche considerare l'utilizzo di boost::lexical_cast. È quasi altrettanto semplice da utilizzare come atoi, ma fornisce anche (approssimativamente) lo stesso livello di dettaglio negli errori di reporting come strtol. La spesa più grande è che può generare eccezioni, quindi per utilizzarlo il codice deve essere protetto dalle eccezioni. Se stai scrivendo C++, dovresti farlo comunque, ma questo tipo di costringe il problema.

1

L'approccio con istringstream può essere migliorata al fine di verificare che nessun altro carattere sono stati inseriti dopo l'argomento previsto:

#include <sstream> 

int main(int argc, char *argv[]) 
{ 
    if (argc >= 2) 
    { 
     std::istringstream iss(argv[1]); 
     int val; 

     if ((iss >> val) && iss.eof()) // Check eofbit 
     { 
      // Conversion successful 
     } 
    } 

    return 0; 
} 
3

std :: stoi da stringa potrebbe anche essere usato.

#include <string> 

    using namespace std; 

    int main (int argc, char** argv) 
    { 
     if (argc >= 2) 
     { 
      int val = stoi(argv[1]); 
      // ...  
     } 
     return 0; 
    } 
Problemi correlati