Argomenti della Riga di Comando in Linguaggio C
In questa lezione studieremo gli argomenti della riga di comando in Linguaggio C.
Gli argomenti della riga di comando sono informazioni aggiuntive che vengono passate a un programma quando viene lanciato da console. Essi vengono passati sotto forma di un array di stringhe. Studieremo, in questa lezione, come accedervi nei nostri programmi scritti in C.
Argomenti della Riga di Comando
Spesso, quando lanciamo un programma dalla riga di comando, cioè dalla console, abbiamo bisogno di passare delle informazioni aggiuntive. Tali informazioni potrebbero essere il nome di un file da processare, il percorso di una cartella dove scrivere l'output, oppure, semplicemente, uno switch, una sorta di flag che attiva o disattiva una funzionalità del programma.
Prendiamo un esempio dal mondo Linux. Se vogliamo visualizzare il contenuto della cartella in cui ci troviamo, possiamo adoperare il comando ls
, contrazione di list
. Tipicamente, se eseguiamo ls
, otteniamo un output del genere:
$ ls
file1.txt file2.txt file3.txt
Tuttavia, se vogliamo visualizzare anche i file nascosti, possiamo passare un argomento al comando ls
. In particolare, possiamo passare l'argomento -a
, che sta per all, ovvero tutti. In questo modo, il comando ls
visualizzerà anche i file nascosti:
$ ls -a
. .. file1.txt file2.txt file3.txt .hiddenfile
Se poi, vogliamo visualizzare informazioni dettagliate sui file, possiamo passare l'argomento -l
, che sta per long, ovvero lungo:
$ ls -l
-rw-r--r-- 1 user user 0 Jan 1 00:00 file1.txt
-rw-r--r-- 1 user user 0 Jan 1 00:00 file2.txt
-rw-r--r-- 1 user user 0 Jan 1 00:00 file3.txt
In questo caso, il comando ls
visualizzerà informazioni dettagliate sui file, come i permessi, il numero di link, il proprietario, il gruppo, la dimensione, la data di creazione e il nome del file.
Ora, questi switch, contrassegnati da un trattino -
, sono detti argomenti della riga di comando. Essi sono opzionali, del resto solo il nome del file o comando da eseguire è obbligatorio, ma attraverso di essi è possibile personalizzare il comportamento del programma.
Queste informazioni aggiuntive prendono il nome di argomenti della riga di comando.
Argomenti della Riga di Comando
Gli argomenti della riga di comando sono informazioni aggiuntive che vengono passate a un programma quando viene eseguito dalla riga di comando.
Essi sono separati dal nome del programma da spazi:
$ nome_programma argomento1 argomento2 argomento3 ...
Accesso agli Argomenti della Riga di Comando
Gli argomenti della riga di comando non sono disponibili soltanto per i comandi del sistema, ma possono essere sfruttati da qualunque programma scritto in C.
Per poter accedere a questi argomenti nel nostro programma dobbiamo, tuttavia, modificare la firma della funzione main
del nostro programma.
In particolare, dobbiamo modificare la funzione main
in maniera tale che accetti due parametri chiamati, tipicamente, argc
e argv
. Per cui la funzione main
diventa:
int main(int argc, char *argv[])
{
// Codice del programma
return 0;
}
Il primo parametro argc
sta per argument count, ovvero contatore degli argomenti. Esso rappresenta il numero totale di argomenti passati al programma, compreso il nome del programma stesso.
Il secondo parametro argv
sta per argument vector, ovvero vettore degli argomenti. Esso è un array di stringhe, dove ogni elemento rappresenta un argomento passato al programma.
In generale, argv[0]
contiene il nome del programma, mentre argv[1]
, argv[2]
, ..., argv[argc-1]
contengono gli argomenti passati al programma. Inoltre, l'array argv
contiene anche un elemento aggiuntivo, argv[argc]
, che è sempre NULL
ossia un puntatore che non punta a nulla. Vedremo meglio il puntatore NULL
nelle prossime lezioni.
In base a quanto detto, se invochiamo un programma prova
in questo modo:
$ ./prova arg1 arg2 arg3
Quello che accade è che:
argc
sarà uguale a4
, poiché abbiamo passato 3 argomenti al programma ma dobbiamo anche contare il suo stesso nome;argv[0]
sarà uguale a"./prova"
, cioè il nome del programma;argv[1]
sarà uguale a"arg1"
, cioè il primo argomento;argv[2]
sarà uguale a"arg2"
, cioè il secondo argomento;argv[3]
sarà uguale a"arg3"
, cioè il terzo argomento;argv[4]
sarà uguale aNULL
.
In memoria, argv
sarà organizzato in questo modo:
Accedere agli Argomenti della Riga di Comando
Dal momento che gli argomenti sono memorizzati in un array, la maggior parte dei programmi, per potervi accedere, implementa un ciclo for
che scorre l'array argv
.
Ad esempio, possiamo scrivere un programma che stampa tutti gli argomenti passati al programma:
#include <stdio.h>
int main(int argc, char *argv[])
{
for (int i = 0; i < argc; i++)
{
printf("Argomento %d: %s\n", i, argv[i]);
}
return 0;
}
Se compiliamo e lanciamo il programma prova
con gli argomenti arg1
, arg2
e arg3
, otteniamo:
$ ./prova arg1 arg2 arg3
Argomento 0: ./prova
Argomento 1: arg1
Argomento 2: arg2
Argomento 3: arg3
Il ciclo for
presente all'interno del programma può essere, in realtà, riscritto in un altro modo. Tenendo conto, infatti, che l'ultimo elemento dell'array argv
è NULL
, possiamo modificare il ciclo for
in questo modo:
char **p;
int i;
for (i = 0, p = argv; *p != NULL; p++, i++) {
printf("Argomento %d: %s\n", i, *p);
}
In questo modo, il ciclo for
scorre l'array argv
fino a quando non trova il puntatore NULL
.
Esempio
Proviamo a scrivere un programma di esempio, che prende dalla riga di comando vari numeri interi e ne calcola la somma.
Prima di poter scrivere il programma, dobbiamo introdurre la funzione atoi
, che converte una stringa in un numero intero. La funzione atoi
è definita nella libreria stdlib.h
.
int atoi(const char *str);
La funzione atoi
prende in input una stringa str
e restituisce il corrispondente numero intero. Se la stringa str
non rappresenta un numero intero, la funzione restituisce 0
.
Iniziamo a realizzare lo scheletro del nostro programma:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int somma = 0;
// Codice del programma
return 0;
}
Per prima cosa, dobbiamo controllare che l'utente abbia effettivamente passato una serie di parametri al programma. Se argc
è minore di 2
, allora l'utente non ha passato alcun parametro. In tal caso, stampiamo un messaggio di errore e terminiamo il programma.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int somma = 0;
if (argc < 2) {
printf("Errore: nessun parametro passato\n");
return -1;
}
// Codice del programma
return 0;
}
A questo punto, possiamo calcolare la somma dei numeri passati come argomenti al programma. Per farlo, dobbiamo scorrere l'array argv
a partire dall'elemento argv[1]
, poiché argv[0]
contiene il nome del programma, e convertire ogni elemento in un numero intero.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int somma = 0;
if (argc < 2) {
printf("Errore: nessun parametro passato\n");
return -1;
}
for (int i = 1; i < argc; i++) {
somma += atoi(argv[i]);
}
printf("La somma dei numeri passati è: %d\n", somma);
return 0;
}
Se compiliamo e lanciamo il programma con i parametri 1
, 2
e 3
, otteniamo:
$ ./somma 1 2 3
La somma dei numeri passati è: 6
La cosa interessante è che se dovessimo inserire un parametro non numerico, la funzione atoi
restituirebbe 0
, e quindi il programma sommerebbe 0
alla somma parziale.
Ad esempio, se lanciamo il programma con i parametri 1
, 2
e ciao
, otteniamo:
$ ./somma 1 2 ciao
La somma dei numeri passati è: 3
In Sintesi
In questa lezione abbiamo studiato gli argomenti della riga di comando in Linguaggio C.
Abbiamo visto che, modificando il prototipo della funzione main
, possiamo accedere agli argomenti passati al programma dalla riga di comando. In particolare, abbiamo visto che la funzione main
accetta due parametri, argc
e argv
, che rappresentano rispettivamente il numero totale di argomenti passati al programma e un array di stringhe contenente gli argomenti stessi.
In particolare, argv
è un array di stringhe, dove ogni elemento rappresenta un argomento passato al programma. L'elemento argv[0]
contiene il nome del programma, mentre gli elementi argv[1]
, argv[2]
, ..., argv[argc-1]
contengono gli argomenti passati al programma. L'elemento argv[argc]
è sempre NULL
.
Infine, abbiamo visto un esempio di programma che calcola la somma dei numeri passati come argomenti dalla riga di comando.