C Language
Argomenti della riga di comando
Ricerca…
Sintassi
- int main (int argc, char * argv [])
Parametri
Parametro | Dettagli |
---|---|
argc | argomento count - inizializzato sul numero di argomenti separati dallo spazio dati al programma dalla riga di comando e sul nome del programma stesso. |
argv | vettore di argomento: inizializzato su una matrice di puntatori di char (stringhe) contenenti gli argomenti (e il nome del programma) forniti sulla riga di comando. |
Osservazioni
Il programma AC in esecuzione in un "ambiente ospitato" (il tipo normale - al contrario di un "ambiente indipendente") deve avere una funzione main
. È tradizionalmente definito come:
int main(int argc, char *argv[])
Si noti che argv
può anche essere, e molto spesso, definito come char **argv
; il comportamento è lo stesso. Inoltre, i nomi dei parametri possono essere modificati perché sono solo variabili locali all'interno della funzione, ma argc
e argv
sono convenzionali e dovresti usare questi nomi.
Per le funzioni main
cui il codice non utilizza argomenti, utilizzare int main(void)
.
Entrambi i parametri sono inizializzati all'avvio del programma:
-
argc
è inizializzato sul numero di argomenti separati dallo spazio dati al programma dalla riga di comando e sul nome del programma stesso. -
argv
è un array dichar
-pointers (stringhe) contenenti gli argomenti (e il nome del programma) che è stato fornito sulla riga di comando. - alcuni sistemi espandono gli argomenti della riga di comando "nella shell", altri no. Su Unix se l'utente digita
myprogram *.txt
il programma riceverà un elenco di file di testo; su Windows riceverà la stringa "*.txt
".
Nota: prima di utilizzare argv
, potrebbe essere necessario controllare il valore di argc
. In teoria, argc
potrebbe essere 0
, e se argc
è zero, allora non ci sono argomenti e argv[0]
(equivalente a argv[argc]
) è un puntatore nullo. Sarebbe un sistema insolito con un ambiente ospitato se si è verificato questo problema. Allo stesso modo, è possibile, sebbene molto insolito, che non ci siano informazioni sul nome del programma. In tal caso, argv[0][0] == '\0'
- il nome del programma potrebbe essere vuoto.
Supponiamo di iniziare il programma in questo modo:
./some_program abba banana mamajam
Quindi argc
è uguale a 4
e gli argomenti della riga di comando:
-
argv[0]
punta a"./some_program"
(il nome del programma) se il nome del programma è disponibile dall'ambiente host. Altrimenti una stringa vuota""
. -
argv[1]
indica"abba"
, -
argv[2]
indica"banana"
, -
argv[3]
indica"mamajam"
, -
argv[4]
contiene il valoreNULL
.
Vedi anche What should main()
return in C e C ++ per le virgolette complete dallo standard.
Stampa degli argomenti della riga di comando
Dopo aver ricevuto gli argomenti, puoi stamparli come segue:
int main(int argc, char **argv)
{
for (int i = 1; i < argc; i++)
{
printf("Argument %d: [%s]\n", i, argv[i]);
}
}
Gli appunti
- Il parametro
argv
può anche essere definito comechar *argv[]
. -
argv[0]
può contenere il nome del programma stesso (a seconda di come è stato eseguito il programma). Il primo argomento di riga di comando "reale" è inargv[1]
, e questo è il motivo per cui la variabile di loopi
è inizializzata su 1. - Nell'istruzione print, puoi usare
*(argv + i)
invece diargv[i]
- valuta la stessa cosa, ma è più dettagliato. - Le parentesi quadre attorno al valore dell'argomento aiutano a identificare l'inizio e la fine. Questo può essere inestimabile se ci sono spazi vuoti finali, newline, ritorni a capo o altri caratteri oddball nell'argomento. Alcune varianti di questo programma sono uno strumento utile per il debug degli script di shell in cui è necessario capire cosa contiene effettivamente l'elenco degli argomenti (sebbene esistano alternative di shell semplici che sono quasi equivalenti).
Stampa gli argomenti in un programma e converti in valori interi
Il seguente codice stamperà gli argomenti per il programma e il codice tenterà di convertire ogni argomento in un numero (a long
):
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <limits.h>
int main(int argc, char* argv[]) {
for (int i = 1; i < argc; i++) {
printf("Argument %d is: %s\n", i, argv[i]);
errno = 0;
char *p;
long argument_numValue = strtol(argv[i], &p, 10);
if (p == argv[i]) {
fprintf(stderr, "Argument %d is not a number.\n", i);
}
else if ((argument_numValue == LONG_MIN || argument_numValue == LONG_MAX) && errno == ERANGE) {
fprintf(stderr, "Argument %d is out of range.\n", i);
}
else {
printf("Argument %d is a number, and the value is: %ld\n",
i, argument_numValue);
}
}
return 0;
}
RIFERIMENTI:
Usare gli strumenti GNU getopt
Le opzioni della riga di comando per le applicazioni non vengono trattate in modo diverso dagli argomenti della riga di comando dal linguaggio C. Sono solo argomenti che, in un ambiente Linux o Unix, iniziano tradizionalmente con un trattino ( -
).
Con glibc in ambiente Linux o Unix è possibile utilizzare gli strumenti getopt per definire, validare e analizzare facilmente le opzioni da riga di comando dal resto degli argomenti.
Questi strumenti si aspettano che le opzioni siano formattate secondo gli standard di codifica GNU , che è un'estensione di ciò che specifica POSIX per il formato delle opzioni della riga di comando.
L'esempio seguente mostra la gestione delle opzioni da riga di comando con gli strumenti GNU getopt.
#include <stdio.h>
#include <getopt.h>
#include <string.h>
/* print a description of all supported options */
void usage (FILE *fp, const char *path)
{
/* take only the last portion of the path */
const char *basename = strrchr(path, '/');
basename = basename ? basename + 1 : path;
fprintf (fp, "usage: %s [OPTION]\n", basename);
fprintf (fp, " -h, --help\t\t"
"Print this help and exit.\n");
fprintf (fp, " -f, --file[=FILENAME]\t"
"Write all output to a file (defaults to out.txt).\n");
fprintf (fp, " -m, --msg=STRING\t"
"Output a particular message rather than 'Hello world'.\n");
}
/* parse command-line options and print message */
int main(int argc, char *argv[])
{
/* for code brevity this example just uses fixed buffer sizes for strings */
char filename[256] = { 0 };
char message[256] = "Hello world";
FILE *fp;
int help_flag = 0;
int opt;
/* table of all supported options in their long form.
* fields: name, has_arg, flag, val
* `has_arg` specifies whether the associated long-form option can (or, in
* some cases, must) have an argument. the valid values for `has_arg` are
* `no_argument`, `optional_argument`, and `required_argument`.
* if `flag` points to a variable, then the variable will be given a value
* of `val` when the associated long-form option is present at the command
* line.
* if `flag` is NULL, then `val` is returned by `getopt_long` (see below)
* when the associated long-form option is found amongst the command-line
* arguments.
*/
struct option longopts[] = {
{ "help", no_argument, &help_flag, 1 },
{ "file", optional_argument, NULL, 'f' },
{ "msg", required_argument, NULL, 'm' },
{ 0 }
};
/* infinite loop, to be broken when we are done parsing options */
while (1) {
/* getopt_long supports GNU-style full-word "long" options in addition
* to the single-character "short" options which are supported by
* getopt.
* the third argument is a collection of supported short-form options.
* these do not necessarily have to correlate to the long-form options.
* one colon after an option indicates that it has an argument, two
* indicates that the argument is optional. order is unimportant.
*/
opt = getopt_long (argc, argv, "hf::m:", longopts, 0);
if (opt == -1) {
/* a return value of -1 indicates that there are no more options */
break;
}
switch (opt) {
case 'h':
/* the help_flag and value are specified in the longopts table,
* which means that when the --help option is specified (in its long
* form), the help_flag variable will be automatically set.
* however, the parser for short-form options does not support the
* automatic setting of flags, so we still need this code to set the
* help_flag manually when the -h option is specified.
*/
help_flag = 1;
break;
case 'f':
/* optarg is a global variable in getopt.h. it contains the argument
* for this option. it is null if there was no argument.
*/
printf ("outarg: '%s'\n", optarg);
strncpy (filename, optarg ? optarg : "out.txt", sizeof (filename));
/* strncpy does not fully guarantee null-termination */
filename[sizeof (filename) - 1] = '\0';
break;
case 'm':
/* since the argument for this option is required, getopt guarantees
* that aptarg is non-null.
*/
strncpy (message, optarg, sizeof (message));
message[sizeof (message) - 1] = '\0';
break;
case '?':
/* a return value of '?' indicates that an option was malformed.
* this could mean that an unrecognized option was given, or that an
* option which requires an argument did not include an argument.
*/
usage (stderr, argv[0]);
return 1;
default:
break;
}
}
if (help_flag) {
usage (stdout, argv[0]);
return 0;
}
if (filename[0]) {
fp = fopen (filename, "w");
} else {
fp = stdout;
}
if (!fp) {
fprintf(stderr, "Failed to open file.\n");
return 1;
}
fprintf (fp, "%s\n", message);
fclose (fp);
return 0;
}
Può essere compilato con gcc
:
gcc example.c -o example
Supporta tre opzioni della riga di comando ( --help
, --file
e --msg
). Tutti hanno anche una "forma breve" ( -h
, -f
, e -m
). Le opzioni "file" e "msg" accettano entrambi gli argomenti. Se si specifica l'opzione "msg", è richiesto l'argomento.
Gli argomenti per le opzioni sono formattati come:
-
--option=value
(per le opzioni di forma lunga) -
-ovalue
o-o"value"
(per opzioni in forma breve)