web-dev-qa-db-fra.com

Passer des arguments dans le programme C à partir de la ligne de commande

Je suis donc sous Linux et je veux qu'un programme accepte les arguments lorsque vous l'exécutez à partir de la ligne de commande.

Par exemple,

./myprogram 42 -b -s

Ainsi, le programme stockerait ce numéro 42 en tant qu'int et exécuterait certaines parties de code en fonction des arguments qu'il obtient comme -b ou -s.

32
BlackCow

Vous pouvez utiliser getopt .

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

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

   opterr = 0;

   while ((c = getopt (argc, argv, "bs")) != -1)
     switch (c)
       {
       case 'b':
         bflag = 1;
         break;
       case 's':
         sflag = 1;
         break;
       case '?':
         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 ("bflag = %d, sflag = %d\n", bflag, sflag);

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

En C, cela se fait en utilisant des arguments passés à votre fonction main():

int main(int argc, char *argv[])
{
    int i = 0;
    for (i = 0; i < argc; i++) {
        printf("argv[%d] = %s\n", i, argv[i]);
    }
    return 0;
}

Plus d'informations peuvent être trouvées en ligne telles que cet article Arguments to main .

25
Greg Hewgill

Pensez à utiliser getopt_long() . Il permet à la fois des options courtes et longues dans n'importe quelle combinaison.

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

/* Flag set by `--verbose'. */
static int verbose_flag;

int
main (int argc, char *argv[])
{
  while (1)
    {
      static struct option long_options[] =
    {
      /* This option set a flag. */
      {"verbose", no_argument,       &verbose_flag, 1},
      /* These options don't set a flag.
         We distinguish them by their indices. */
      {"blip",    no_argument,       0, 'b'},
      {"slip",    no_argument,       0, 's'},
      {0,         0,                 0,  0}
    };
      /* getopt_long stores the option index here. */
      int option_index = 0;

      int c = getopt_long (argc, argv, "bs",
               long_options, &option_index);

      /* Detect the end of the options. */
      if (c == -1)
    break;

      switch (c)
    {
    case 0:
      /* If this option set a flag, do nothing else now. */
      if (long_options[option_index].flag != 0)
        break;
      printf ("option %s", long_options[option_index].name);
      if (optarg)
        printf (" with arg %s", optarg);
      printf ("\n");
      break;
    case 'b':
      puts ("option -b\n");
      break;
    case 's':
      puts ("option -s\n");
      break;
    case '?':
      /* getopt_long already printed an error message. */
      break;

    default:
      abort ();
    }
    }

  if (verbose_flag)
    puts ("verbose flag is set");

  /* Print any remaining command line arguments (not options). */
  if (optind < argc)
    {
      printf ("non-option ARGV-elements: ");
      while (optind < argc)
    printf ("%s ", argv[optind++]);
      putchar ('\n');
    }

  return 0;
}

En relation:

11
jfs

Jetez un œil à la bibliothèque getopt; c'est à peu près l'étalon-or pour ce genre de chose.

7
womble

Au lieu de getopt(), vous pouvez également envisager d'utiliser argp_parse() (une interface alternative à la même bibliothèque).

De manuel libc :

getopt est plus standard (sa version à option courte seulement fait partie de la norme POSIX), mais en utilisant argp_parse est souvent plus facile, à la fois pour les structures d'options très simples et très complexes, car il fait plus de sale boulot pour vous.

Mais j'ai toujours été satisfait de la norme getopt.

N.B. GNU getopt avec getopt_long est GNU LGPL.

5
sastanin

D'autres ont frappé celui-ci sur la tête:

  • les arguments standard de main(int argc, char **argv) vous donnent un accès direct à la ligne de commande (après qu'elle a été modifiée et tokenisée par le Shell)
  • il existe des fonctionnalités très standard pour analyser la ligne de commande: getopt() et getopt_long()

mais comme vous l'avez vu, le code pour les utiliser est un peu verbeux et assez idomatique. Je le pousse généralement hors de vue avec quelque chose comme:

typedef
struct options_struct {
   int some_flag;
   int other_flage;
   char *use_file;
} opt_t;
/* Parses the command line and fills the options structure, 
 * returns non-zero on error */
int parse_options(opt_t *opts, int argc, char **argv);

Puis la première chose principale:

int main(int argc, char **argv){
   opt_t opts;
   if (parse_options(&opts,argc,argv)){
      ...
   } 
   ...
}

Ou vous pouvez utiliser l'une des solutions suggérées dans Assistants d'analyse des arguments pour C/UNIX .

4
dmckee