J'ai lu un exemple de getopt () mais cela ne montre pas comment accepter les entiers comme options d'argument, comme cvalue
serait dans le code de l'exemple:
#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 j’exécutais ce qui précède comme testop -c foo
, cvalue
serait foo
, mais que se passerait-il si je voulais testop -c 42
? Puisque cvalue
est de type char *
, pourrais-je simplement transtyper optarg
pour être (int)
? J'ai essayé de le faire sans utiliser getopt()
, ni accéder directement à argv[whatever]
, ni le convertir en tant qu'entier, mais je finis toujours avec un grand nombre négatif lors de l'impression avec %d
. Je suppose que je ne suis pas en train de déréférencer argv[]
correctement ou quelque chose comme ça, je ne suis pas sûr ...
Vous devez utiliser atoi()
pour convertir une chaîne en entier.
Toutes les réponses ci-dessus sont globalement correctes (Vikram.exe obtient des accessoires pour expliquer pourquoi vous devez appeler une fonction de bibliothèque, ce que personne d'autre n'a pris la peine de faire). Cependant, personne n'a appelé la fonction de bibliothèque correct à appeler. Ne pas utiliser atoi
. Ne pas utiliser sscanf
.
Utilisez strtol
, ou son parent strtoul
si vous ne souhaitez pas autoriser les nombres négatifs. Seules ces fonctions vous donnent suffisamment d’informations lorsque l’entrée était pas un nombre. Par exemple, si l'utilisateur tape
./a.out 123cheesesandwich
atoi
et sscanf
renverront joyeusement 123, ce qui n'est certainement pas ce que vous voulez. Seule strtol
vous dira (via la endptr
) qu'elle n'a traité que les premiers caractères de la chaîne.
(Il n'y a pas strtoi
, mais il y a strtod
si vous devez lire un nombre à virgule flottante.)
Comme vous l'avez déjà utilisé dans votre code, le prototype de la fonction main
est
int main (int argc, char** argv)
Quels que soient les arguments fournis en tant qu'arguments de ligne de commande, ils sont transmis à votre 'programme' sous la forme d'un tableau de caractères char * (ou simplement de chaînes). donc, si vous appelez un prog sous la forme foo.exe 123
, le premier argument de foo.exe
sera une chaîne 123 et non une valeur entière de 123.
Si vous essayez de transformer l'argument en entier (comme vous l'avez dit) en utilisant probablement quelque chose comme: (int) argv[1]
, vous n'obtiendrez pas la valeur entière du premier argument, mais une adresse mémoire où le premier argument est stocké dans votre espace adresse. . Pour obtenir une valeur entière, vous devez convertir explicitement la valeur de chaîne en valeur entière. Pour cela, vous pouvez utiliser la fonction atoi
. Consultez la page de manuel THIS pour connaître les fonctions similaires pouvant être utilisées pour la conversion.
Utilisez atoi
.
cvalue = atoi( optarg );
Et déclarer cvalue en tant que int
.
atoi()
, ce qui signifie ascii en entier est la fonction à utiliser. De même, atof()
peut être utilisé pour obtenir des valeurs flottantes.
Dans cette situation, j'irais pour un sscanf()
.
Non, vous ne pouvez pas simplement convertir pour le convertir en une valeur entière. Vous devez le transformer en utilisant sscanf, atoi, atol ou une fonction similaire.