next up previous contents index
Next: Tipi primitivi Up: Approfondimenti. I files d'intestazione Previous: Argomenti con valori default   Indice   Indice analitico

Argomenti da linea di comando

Fino a questo punto abbiamo considerato sempre la funzione main come una funzione void senza argomenti; in realtà non è così : la dichiarazione usuale della funzione principale è

int main (int argc, char** argv)
Il valore di ritorno della main indica lo stato di uscita del programma; se non ci sono stati errori di esecuzione allora il programma esce con codice 0, altrimenti di solito viene restituito 1. Comunque non ci occuperemo affatto del significato che può avere il valore di ritorno di un programma; si noti tuttavia che se si dichiara int la funzione principale allora, come per tutte le altre funzioni, deve essere tornato un valore intero8.2.

A cosa servono invece gli argomenti della main? Se si è utilizzato esclusivamente il sistema operativo Windows, è ben difficile che si sia eseguito un programma dalla riga di comando; gli utenti di altri sistemi operativi dovrebbero invece sapere perfettamente di cosa essa si tratti. Vediamo di parlarne brevemente; quando viene eseguito un programma, è possibile passargli degli argomenti che influenzano il funzionamento di esso. Supponiamo di volere compilare da riga di comando il nostro primo programma di esempio (ex2_1_1.cpp); immaginiamo inoltre di avere il compilatore GNU GCC (gratuito e disponibile in Internet su numerosissimi mirror, come ftp://ftp.unina.it). Se abbiamo a nostra disposizione una macchina Windows 9x/NT/2000, dobbiamo aprire una finestra ``prompt di MS-DOS''; dopo esserci portati nella cartella contenente il file ex2_1_1.cpp, dobbiamo eseguire il seguente comando:

gxx ex2_1_1.cpp -o esempio.exe
il quale provvederà a compilare il codice contenuto in ex2_1_1.cpp ed a collegarlo al file esempio.exe. Il nome del file eseguibile che abbiamo utilizzato è gxx.exe 8.3; il resto del comando è costituito da 3 argomenti, separati da uno spazio: ex2_1_1.cpp, -o e esempio.exe: tali argomenti servono al programma gxx per stabilire il file da compilare (primo argomento) e il nome del file eseguibile che sarà generato (terzo argomento).

Se vogliamo che anche un nostro programma sia in grado di accettare e gestire degli argomenti, dobbiamo agire sui parametri argc e argv. Il primo di essi specifica semplicemente il numero degli argomenti. Vediamo un esempio:


// ex8_3_1
#include <iostream.h>
int main (int argc, char** argv) {
  cout << "numero argomenti: " << argc << "\n";
  return 0;  // attenzione: il ritorno e` necessario
}

esempio di esecuzione:
gxx ex8_3_1.cpp -o prova.exe
prova ciao ciao

output:
numero argomenti: 3

Per quale motivo vengono segnalati 3 argomenti mentre ne abbiamo passati solo due (ciao ciao)? Perché viene conteggiato come primo argomento anche il nome del file eseguito. La variabile argv, come ci si può aspettare, contiene invece gli argomenti veri e propri, sotto forma di array di stringhe (ecco spiegato il misterioso tipo char**). Un semplice esempio che stampa gli argomenti passati al programma è il seguente:


// ex8_3_2
#include <iostream.h>

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

esempio di esecuzione:
gxx ex8_3_2.cpp -o prova.exe
prova arg1 arg2

output:
prova
arg1
arg2

Gli argomenti sono utilizzati ampiamente in tutti i programmi privi di una interfaccia grafica, i quali tuttavia in pratica non esistono nella sfera dei moderni sistemi operativi Microsoft, che supponiamo essere utilizzati dalla maggior parte dei lettori. Ci limiteremo dunque a fornire solo un paio di altri esempi sull'argomento.


// ex8_3_3
#include <iostream.h>
#include <stdlib.h>
#include <time.h>

int main (int argc, char** argv) {
  if (argc <= 1) {
    cout << "la sintassi e`:"
      "\ncasuale max [n]"
      "\n\tove max e` il massimo numero casuale restituito"
      "\n\te n (opzionale) indica quanti numeri restituire\n";
    return 1;  // codice di errore
  }
  // strtol converte una stringa in un intero
  int max = strtol (argv[1], 0, 10);
  int n;
  if (argc >= 3)
    n = strtol (argv[2], 0, 10);
  else
    n = 1;  // valore default nel caso `n' non venga fornito
  srand ( time(0) );
  for (int i = 0; i < n; i++)
    cout << (rand() % max + 1) << "\n";
  return 0;
}

esempio di esecuzione:
gxx ex8_3_3.cpp -o casuale.exe
casuale 90 3

output:
38
11
87

esempio di esecuzione:
casuale 6

output:
5

Come si vede è possibile fare in modo che il programma restituisca dei numeri casuali, indicando a esso quanti estrarne ed il massimo valore direttamente dalla riga di comando: davvero molto comodo. Nell'esempio precedente c'è solo una funzione che risulta ignota: strtol; essa appartiene alla libreria stdlib.h e serve a convertire i primi caratteri di una stringa in un intero. La sintassi esatta è:

int strtol (const char* s, char* t, int base)
ove s è la stringa da convertire in intero, e base è la base nella quale effettuare la conversione; si può tralasciare il significato di t semplicemente passando un puntatore nullo. Vediamo un esempio:

// ex8_3_$
#include <iostream.h>
#include <stdlib.h>

void main() {
  char* s = "101110";
  char* t = "0x6f1";
  char* w = "-437";
  cout << s << " = " << strtol(s,0,2) << "\n";
  cout << t << " = " << strtol(t,0,16) << "\n";
  cout << w << " = " << strtol(w,0,10) << "\n";
}

output:
101110 = 46
0x6f1 = 1777
-437 = -437

Il prossimo esempio calcola l'area di una figura geometrica.


// ex8_3_5
#include <iostream.h>
#include <string.h>

void quadrato() {
  double a;
  cout << "lato? "; cin >> a;
  cout << "area: " << a*a;
}

void rettangolo() {
  double a, b;
  cout << "base? "; cin >> a;
  cout << "altezza? "; cin >> b;
  cout << "area: " << a*b;
}

void triangolo() {
  double a, b;
  cout << "base? "; cin >> a;
  cout << "altezza? "; cin >> b;
  cout << "area: " << a*b*.5;
}

void guida() {
  cout << "sintassi:"
    "\n\tarea FIGURA"
    "\nove FIGURA puo` essere una delle seguenti:"
    "\n\tquadrato"
    "\n\trettangolo"
    "\n\ttriangolo\n";
}

void errore() {
  cout << "scrivi `area --help' per la guida\n";
}

int main (int argc, char** argv) {
  if (argc <= 1) {
    errore();
    return 1;
  }
  if ( strcasecmp (argv[1], "quadrato") == 0)
    quadrato();
  else if ( strcasecmp (argv[1], "rettangolo") == 0)
    rettangolo();
  else if ( strcasecmp (argv[1], "triangolo") == 0)
    triangolo();
  else if ( strcasecmp (argv[1], "--help") == 0)
    guida();
  else {
    errore();
    return 1;
  }
  return 0;
}

esempio di esecuzione:
gxx ex8_3_3.cpp -o area.exe
area

output:
scrivi `area -help' per la guida

esempio di esecuzione:
area -help

output:
sintassi:
area FIGURA
ove FIGURA puo` essere una delle seguenti:
quadrato
rettangolo
triangolo

esempio di esecuzione:
area rettangolo

esempio di output:
base? 6
altezza? 3.5
area: 21

ex-2
si scriva un programma che accetti una stringa come argomento da linea di comando e la stampi al contrario;
ex-3
si scriva un programma che accetti due interi come argomento da linea di comando e stampi la loro somma;


next up previous contents index
Next: Tipi primitivi Up: Approfondimenti. I files d'intestazione Previous: Argomenti con valori default   Indice   Indice analitico
Claudio Cicconetti
2000-09-06