Comment obtenir une valeur de optarg
Question
Salut, je suis en train d'écrire un programme simple client-serveur. Dans ce programme, je dois utiliser getopt()
pour obtenir le numéro de port et l'adresse IP comme ceci:
serveur -i 127.0.0.1 -p 10001
Je ne sais pas comment puis-je obtenir des valeurs de optarg, pour une utilisation ultérieure dans le programme.
La solution
Que diriez-vous comme ceci:
char buf[BUFSIZE+1];
snprintf(buf,BUFSIZE,"%s",optarg);
Ou dans un exemple plus complet:
#include <stdio.h>
#include <unistd.h>
#define BUFSIZE 16
int main( int argc, char **argv )
{
char c;
char port[BUFSIZE+1];
char addr[BUFSIZE+1];
while(( c = getopt( argc, argv, "i:p:" )) != -1 )
switch ( c )
{
case 'i':
snprintf( addr, BUFSIZE, "%s", optarg );
break;
case 'p':
snprintf( port, BUFSIZE, "%s", optarg );
break;
case '?':
fprintf( stderr, "Unrecognized option!\n" );
break;
}
return 0;
}
Pour plus d'informations, consultez la documentation de Getopt .
Autres conseils
Vous utilisez une boucle while pour se déplacer à travers tous les arguments et les traiter comme si ...
#include <unistd.h>
int main(int argc, char *argv[])
{
int option = -1;
char *addr, *port;
while ((option = getopt (argc, argv, "i:p:")) != -1)
{
switch (option)
{
case 'i':
addr = strdup(optarg);
break;
case 'p':
port = strdup(optarg);
break;
default:
/* unrecognised option ... add your error condition */
break;
}
}
/* rest of program */
return 0;
}
Il est l'un des nombreux défauts de la documentation getopt: il ne dit pas clairement que optarg doit être copié pour une utilisation ultérieure (en utilisant strdup (), par exemple), car il peut être remplacé par des options plus tard ou tout simplement libéré plaine par getopt.
Dans le cas d'un IP et le port que vous ne avez pas besoin de stocker les chaînes. Il suffit de les analyser et stocker les valeurs dans un sockaddr.
#include <arpa/inet.h> // for inet_ntop, inet_pton
#include <getopt.h> // for getopt, optarg
#include <netinet/in.h> // for sockaddr_in, etc
#include <stdio.h> // for fprintf, printf, stderr
#include <stdlib.h> // for atoi, EXIT_SUCCESS
#include <string.h> // for memset
#include <sys/socket.h> // for AF_INET
int main(int argc, char *argv[])
{
struct sockaddr_in sa;
char c;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = htonl(INADDR_ANY);
sa.sin_port = 0;
while ((c = getopt(argc, argv, "i:p:")) != -1)
{
switch (c)
{
case 'p':
sa.sin_port = htons(atoi(optarg));
break;
case 'i':
inet_pton(AF_INET, optarg, &(sa.sin_addr));
break;
case '?':
fprintf(stderr, "Unknown option\n");
break;
} /* ----- end switch ----- */
}
char str[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(sa.sin_addr), str, INET_ADDRSTRLEN);
printf("%s:%d\n", str, ntohs(sa.sin_port));
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */