Argomenti dalla linea dei comandi Gli argomenti possono essere passati a qualsiasi funzione di un programma, compresa la main(), direttamente dalla linea dei comandi. Così, mentre il programma vendite.exe viene eseguito scrivendo semplicemente dalla linea dei comandi C> vendite per eseguire lo stesso programma passando alla sua funzione main() gli argomenti filiale, sede si scriverebbe: C:\> vendite filiale sede Quando riceve la precedente linea di comandi, il sistema operativo la memorizza come una sequenza di tre stringhe, ciascuna delle quali termina con il carattere NULL ( \0 ):
Affinché la funzione main() possa accettare gli argomenti che le vengono passati, è sufficiente che la sua definizione contenga un numero e un vettore: il numero è una variabile intera, di nome argc (da argument counter), che indica il numero totale di voci della linea dei comandi (nel nostro caso 3: il nome del programma e i due argomenti); il vettore è una lista unidimensionale, di nome argv (da argument values), costituita dai puntatori che contengono gli indirizzi di partenza in cui sono memorizzate le singole stringhe digitate nella linea dei comandi (vedi figura)
Ricordando allora che argc è un intero e argv un vettore i cui elementi sono indirizzi che puntano alle locazioni dove sono memorizzati gli effettivi comandi della linea dei comandi, lintestazione della funzione che riceve i due argomenti è: void main(int argc, char *argv[]) Il seguente programma argomenti verifica la precedente descrizione stampando i dati effettivamente passati a main() ; in esso la variabile argv[i] contiene un indirizzo, mentre la notazione char *argv[i] si può leggere: argv è un vettore i cui elementi sono puntatori a caratteri. #include /* nome programma: argomenti */ void main(int argc, char *argv[]) { int i; printf("\nIl n° di voci nella linea dei comandi è %d\n\n",argc); for (i = 0; i < argc; i++) { printf("Lindirizzo memorizzato in argv[%d] è %p\n",i,argv[i]); printf("Il carattere puntato è %c\n", *argv[i]); }
Si osservi il diverso risultato che si ottiene eseguendo il programma argomenti con il comando C:\> argomenti oppure con un comando del tipo C:\> argomenti a b c Una volta che gli argomenti siano passati a un programma dalla linea dei comandi, essi possono essere usati come qualsiasi altra stringa. Il seguente programma argomain fa visualizzare gli argomenti della linea dei comandi dallinterno della funzione main(). #include /* nome programma: argomain */ void main(int argc, char *argv[]) { int i; printf(\nI seguenti argomenti sono passati a main(): ); for (i = 1; i < argc; i++) printf(%s, argv[i]); printf(\n); }
Se si esegue il programma argomain scrivendo il comando C:\> argomain vendite filiale si ottiene la seguente uscita: I seguenti argomenti sono passati a main(): vendite filiale Osservazione. Quando nel programma argomain gli indirizzi in argv[] sono passati alla funzione printf(), vengono visualizzate le stringhe puntate da questi indirizzi. Quando gli stessi indirizzi sono stati passati alla funzione printf() nel programma argomenti, sono stati visualizzati i valori attuali degli indirizzi. La differenza nella visualizzazione è causata dalla funzione printf() : quando in essa si usa una sequenza di controllo %s (come nel programma argomain ), essa avverte la funzione che si accederà a una stringa. Quindi printf() si aspetta lindirizzo del primo carattere della stringa, che viene appunto fornito da ogni elemento di argv[].
Quando printf() riceve lindirizzo, essa esegue la indirezione necessaria per localizzare leffettiva stringa che viene visualizzata. La sequenza di controllo %p usata nel programma argomenti visualizza il valore dellindirizzo memorizzato in argv[i]. Come abbiamo già notato, dato che i puntatori sono un tipo di dati unico, C fornisce la specifica sequenza di controllo - %p - per luscita degli indirizzi memorizzati in variabili puntatore. Osservazione. Poiché ogni argomento scritto nella linea dei comandi è considerato una stringa, se si vogliono passare a main() dati numerici è necessario convertire dapprima le stringhe in numeri. Tuttavia ciò è raramente necessario, dato che la maggior parte degli argomenti della linea dei conandi sono usati come indicatori per passare a un programma gli opportuni segnali di controllo dellelaborazione.
Copia di un file. Come esempio di utilizzazione del passaggio di parametri a una funzione dalla linea dei comandi, modifichiamo il precedente programma copiafile nel seguente copiargo, in modo che riceva come parametri dalla linea dei comandi il nome del file da copiare (ad es. salve.txt ) e di quello copiato (ad es. salvebis ).
#include /* nome del programma: copiargo */ int main(int argc, char *argv[]) { FILE *in_file; FILE *out_file; int c; if(argc != 3) printf("Errore nel numero dei parametri\n"); else { if((in_file=fopen(argv[1], "r")) != NULL) { if((out_file=fopen(argv[2], "w")) != NULL) { while((c=fgetc(in_file)) != EOF) fputc(c, out_file); } else printf("Il file \"%s\" non può essere aperto\n",argv[2]); } else printf("Il file \"%s\" non può essere aperto\n",argv[1]); }
Quando si esegue il programma copiargo, se nella linea dei comandi non sono stati indicati tre argomenti ( argc è diverso da 3) viene visualizzato un messaggio di errore e il programma termina. In caso contrario, il vettore argv[] contiene le stringhe copiargo, salve.txt e salvebis, le ultime due delle quali sono usate dal programma come nomi di file, che saranno aperti dalla funzione fopen(). Se entrambi i file sono aperti con successo, vengono letti i caratteri dal file salve.txt e scritti nel file salvebis finché nel primo non si incontra il carattere di fine-file, che fa terminare lesecuzione del programma. Il risultato sarà una copia esatta del file salve.txt nel file salvebis.
Reindirizzamento di input e output (operatore > ) La visualizzazione prodotta dalla funzione printf() viene di solito inviata al terminale di lavoro. Esso è detto dispositivo di uscita standard perché è il posto al quale, in condizioni standard, linterfaccia tra il programma C e il sistema operativo del computer indirizza automaticamente la visualizzazione. È tuttavia possibile reindirizzare luscita prodotta da printf() verso un altro dispositivo, o verso un file, tramite loperatore di reindirizzamento > nel momento in cui si chiama il programma. Oltre al simbolo, si deve specificare dove si vuole che siano inviati i risultati visualizzati. Ad es., supponiamo che per eseguire un programma si debba impartire, al prompt del sistema, il comando C:\> vendite
Se vogliamo che la visualizzazione prodotta dal programma sia inviata, anziché allo schermo al file di nome risultati, dovremo impartire il comando C:\> vendite > risultati Il simbolo di reindirizzamento > dice al sistema operativo di inviare ogni visualizzazione prodotta da printf() direttamente al file di nome risultati, anziché al dispositivo di uscita standard usato dal sistema. La visualizzazione inviata a risultati può poi essere esaminata con un programma di editazione o un opportuno comando del sistema operativo (in Linux il contenuto del file di testo risultati si visualizza con il comando cat risultati, in MS-DOS il comando type risultati ). Nel reindirizzamento si possono verificare due casi: -se il file non esiste, esso viene creato; -se il file esiste, esso viene sovrascritto.
Aggiunta di input e output (operatore >> ) Analogo alloperatore di reindirizzamento, è loperatore di aggiunta delloutput >>, che si usa come loperatore di reindirizzamento, ma fa sì che ogni nuovo output sia aggiunto alla fine di un file. Ad esempio il comando C:\> vendite >> risultati fa sì che ogni output prodotto da vendite sia aggiunto alla fine di risultati. Se il file risultati non esiste, viene creato.