2011-01-25 21 views
17

He leído a getopt() example pero no muestra cómo aceptar enteros como opciones de argumentos, como cvalue habría en el código del ejemplo:cómo tomar enteros como argumentos de línea de 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; 
} 

Si me encontré con lo anterior como testop -c foo, habría cvaluefoo, pero ¿y si quisiera testop -c 42? Dado que cvalue es del tipo char *, ¿podría simplemente convertir optarg en (int)? Intenté hacer esto sin usar getopt() y acceder directamente al argv[whatever], y convertirlo en un número entero, pero siempre termino con un número negativo grande al imprimir con %d. Supongo que no estoy desreferenciando argv[] correctamente o algo así, no estoy seguro ...

Respuesta

34

Debe usar atoi() para convertir de cadena a entero.

4

Use atoi.

cvalue = atoi(optarg); 

Y declarar cValue como int.

1

En esta situación, me gustaría un sscanf().

0

No, no puedes convertir para convertirlo en un valor entero. Necesita transformarlo usando sscanf, atoi, atol o una función similar.

10

Como ya se ha utilizado en su código, el prototipo de main función es

int main (int argc, char** argv)

Lo que alguna vez los argumentos son proporcionados como argumentos de línea de comandos, se pasan a su 'programa' como una matriz de char * (o simplemente cuerdas). por lo que si se invoca como un prog foo.exe 123, el primer argumento de foo.exe será una cadena 123 y no un valor entero de 123.

Si intenta transmitir el argumento a un entero (como usted ha dicho), probablemente usando algo como: (int) argv[1], no obtendrá el valor entero del primer argumento, sino alguna dirección de memoria donde se almacena el primer arg en su espacio de direcciones. Para obtener un valor entero, debe convertir explícitamente el valor de cadena a valor entero. Para esto, puede usar la función atoi. Consulte THIS página de manual para funciones similares que se pueden usar para la conversión.

16

Todas las respuestas anteriores son ampliamente correctas (Vikram.exe obtiene accesorios para explicar por qué tiene que llamar a una función de biblioteca, que nadie más se molestó en hacer). Sin embargo, nadie ha llamado a la función de biblioteca correcta para llamar. No use atoi. No use sscanf.

Utilice strtol, o su pariente strtoul si no desea permitir números negativos. Solo estas funciones le brindan suficiente información cuando la entrada era y no un número. Por ejemplo, si el usuario escribe

./a.out 123cheesesandwich 

atoisscanf y se alegremente devolver 123, que es casi seguro que no lo desea.Solo strtol le dirá (a través del endptr) que procesó solo los primeros caracteres de la cadena.

(no hay strtoi, pero hay strtod si necesita leer un número de coma flotante.)

4

atoi(), lo que significa ASCII a entero es la función de su uso. Del mismo modo, atof() se puede utilizar para obtener valores flotantes.

Cuestiones relacionadas