2011-01-25 17 views
17

Ho letto a getopt() example ma non mostra come accettare interi come opzioni argomento, come cvalue sarebbe nel codice dall'esempio:come prendere interi come argomenti della riga di comando?

#include <ctype.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

int 
main (int argc, char **argv) 
{ 
    int aflag = 0; 
    int bflag = 0; 
    char *cvalue = NULL; 
    int index; 
    int c; 

    opterr = 0; 

    while ((c = getopt (argc, argv, "abc:")) != -1) 
    switch (c) 
     { 
     case 'a': 
     aflag = 1; 
     break; 
     case 'b': 
     bflag = 1; 
     break; 
     case 'c': 
     cvalue = optarg; 
     break; 
     case '?': 
     if (optopt == 'c') 
      fprintf (stderr, "Option -%c requires an argument.\n", optopt); 
     else if (isprint (optopt)) 
      fprintf (stderr, "Unknown option `-%c'.\n", optopt); 
     else 
      fprintf (stderr, 
        "Unknown option character `\\x%x'.\n", 
        optopt); 
     return 1; 
     default: 
     abort(); 
     } 

    printf ("aflag = %d, bflag = %d, cvalue = %s\n", 
      aflag, bflag, cvalue); 

    for (index = optind; index < argc; index++) 
    printf ("Non-option argument %s\n", argv[index]); 
    return 0; 
} 

Se ho eseguito quanto sopra come testop -c foo, cvalue sarebbe foo, ma cosa succede se volevo testop -c 42? Dal cvalue è di tipo char *, potrei semplicemente trasmettere optarg per essere (int)? Ho provato a farlo senza usare getopt() e accedere direttamente a argv[whatever] e a lanciarlo come numero intero, ma alla fine mi ritrovo sempre con un numero negativo grande quando stampo con %d. Suppongo che non stia effettuando il dereferimento argv[] correttamente o qualcosa del genere, non sono sicuro ...

risposta

34

È necessario utilizzare atoi() per convertire da stringa a intero.

4

Utilizzare atoi.

cvalue = atoi(optarg); 

E dichiarare cValue come int.

1

In questa situazione vorrei andare per un sscanf().

0

No, non è possibile eseguire il cast per convertirlo in un valore intero. Devi trasformarlo usando sscanf, atoi, atol o funzioni simili.

10

Come avete già utilizzato nel codice, il prototipo per main funzione è

int main (int argc, char** argv)

Che cosa mai gli argomenti sono forniti come argomenti della riga di comando, sono passati al 'programma' come una matrice di char * (o semplicemente stringhe). quindi se si richiama un prog come foo.exe 123, il primo argomento di foo.exe sarà una stringa 123 e non un valore intero di 123.

Se si tenta di lanciare l'argomento per intero (come hai detto), probabilmente con qualche cosa come: (int) argv[1], non si otterrà il valore intero del primo argomento, ma un indirizzo di memoria in cui il primo argomento è memorizzato nello spazio degli indirizzi. Per ottenere un valore intero, è necessario convertire esplicitamente il valore stringa in intero. Per questo, è possibile utilizzare la funzione atoi. Controllare la pagina man THIS per funzioni simili che possono essere utilizzate per la conversione.

16

Tutte le risposte di cui sopra sono ampiamente corrette (Vikram.exe ottiene puntelli per spiegare perché devi chiamare una funzione di libreria, che nessun altro si è preso la briga di fare). Tuttavia, nessuno ha chiamato la funzione di libreria corretta per chiamare . Non utilizzare atoi. Non utilizzare sscanf.

Utilizzare strtol o il relativo strtoul se non si desidera consentire numeri negativi. Solo queste funzioni forniscono informazioni sufficienti quando l'input era non un numero. Per esempio, se l'utente digita

./a.out 123cheesesandwich 

atoi e sscanf saranno allegramente ritorno 123, che è quasi certamente non quello che volete.Solo strtol ti dirà (tramite lo endptr) che ha elaborato solo i primi caratteri della stringa.

(Non c'è strtoi, ma c'è strtod se è necessario leggere un numero in virgola mobile.)

4

atoi(), che significa ASCII intero è la funzione da utilizzare. Allo stesso modo, è possibile utilizzare atof() per ottenere valori float.

Problemi correlati