9 Altre Istruzioni Di I O

1,507 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,507
On SlideShare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
48
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

9 Altre Istruzioni Di I O

  1. 1. INFORMATICA Altre Istruzioni di I/O
  2. 2. Funzioni di I/O <ul><li>Per la lettura e la scrittura da videoterminale il C prevede numerose istruzioni tra cui scanf e printf che, come abbiamo già visto, agiscono su tutti i tipi di dato semplici. </li></ul><ul><li>  </li></ul><ul><li>scanf e printf sono in realtà funzioni di tipo int e, come tali, ritornano un valore intero attraverso il loro nome. </li></ul><ul><li>La scanf restituisce il numero di parametri letti correttamente: se la si richiama con un unico parametro (cioè si intende leggere un solo dato), il valore restituito è 1 se la lettura è andata a buon fine, 0 in caso di errore. </li></ul><ul><li>La printf restituisce invece il numero di bytes che ha inviato in output, oppure 0 in caso di errore. </li></ul>
  3. 3. Funzioni di I/O <ul><li>Nel seguente frammento di programma: </li></ul><ul><li>int ndati, dato; </li></ul><ul><li>....... </li></ul><ul><li>ndati = scanf (“%d”, &dato); </li></ul><ul><li>in ndati verrebbe restituito il valore 1. </li></ul><ul><li>Nella lettura di dati da tastiera non è previsto alcun codice particolare per segnalare il fatto che i dati in ingresso sono finiti. </li></ul><ul><li>  </li></ul><ul><li>Talvolta, per questo evento, si può usare una combinazione particolare: premendo contemporaneamente i tasti CTRL (control) e Z il Sistema Operativo interpreta quella combinazione come valore particolare chiamato EOF e definito internamente). </li></ul>
  4. 4. Esempio <ul><li>Programma che calcola il valor medio di un certo numero di dati reali (non noto a priori) terminanti con EOF, introdotti da terminale. </li></ul><ul><li>  </li></ul><ul><li>#include <stdio.h> </li></ul><ul><li>#define VERO 1 </li></ul><ul><li>#define FALSO 0 </li></ul><ul><li>  </li></ul><ul><li>main() </li></ul><ul><li>{ </li></ul><ul><li>double numero, somma, media; </li></ul><ul><li>int numdati, stato; </li></ul><ul><li>short int fine_lettura; </li></ul>
  5. 5. Esempio <ul><li>fine_lettura = FALSO; /* inizializza flag, */ </li></ul><ul><li>somma = 0.0; /* accumulatore risultato */ </li></ul><ul><li>numdati = 0; /* contatore dei dati introdotti */ </li></ul><ul><li>printf (&quot;Introduci i dati (reali), CTRL+Z per finire: &quot;); </li></ul><ul><li>while (!fine_lettura) /* continua fino al CTRL+Z */ </li></ul><ul><li>{ </li></ul><ul><li>stato = scanf (&quot;%lf&quot;, &numero); /* in stato numero dati letti */ </li></ul><ul><li>if (stato == 1) </li></ul><ul><li>{ </li></ul><ul><li>somma += numero; /* accumula in somma */ </li></ul><ul><li>numdati++; /* incrementa numdati (dati letti correttamente) */ </li></ul><ul><li>} </li></ul><ul><li>else </li></ul><ul><li>fine_lettura = VERO; /* fine lettura */ </li></ul><ul><li>} /* fine di while NOT fine_lettura */ </li></ul>
  6. 6. Esempio <ul><li>if (numdati == 0) </li></ul><ul><li>printf (“ Media non calcolabile&quot;); </li></ul><ul><li>else </li></ul><ul><li>{ </li></ul><ul><li>media = somma / (double)numdati; </li></ul><ul><li>printf (“ La media su %d dati e': %lf&quot;, numdati, media); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>Oltre alla scanf e alla printf il C possiede numerose altre funzioni di lettura e scrittura sia di caratteri sia di altri tipi di dato. </li></ul>
  7. 7. getchar() <ul><li>Lettura di un carattere da tastiera: </li></ul><ul><li>getchar(); </li></ul><ul><li>La funzione senza parametri getchar è definita in stdio.h di tipo intero ( int ) e restituisce un numero intero corrispondente al codice del tasto premuto. </li></ul><ul><li>  </li></ul><ul><li>In caso di fine file fornisce il valore particolare EOF (per la maggior parte dei sistemi vale -1) il quale è predefinito come simbolo in stdio.h . </li></ul><ul><li>  </li></ul><ul><li>Se si esclude il caso dell' EOF è lecito assegnare il valore fornito da questa funzione ad una variabile di tipo carattere ( char ). </li></ul>
  8. 8. Esempio <ul><li>#include <stdio.h> </li></ul><ul><li>  </li></ul><ul><li>main() </li></ul><ul><li>{ </li></ul><ul><li>int carat; </li></ul><ul><li>printf (&quot;Inserisci dei caratteri, CTRL+Z per finire &quot;); </li></ul><ul><li>while ( ( carat = getchar() ) != EOF) </li></ul><ul><li>printf (&quot;%c&quot;, carat); </li></ul><ul><li>} </li></ul><ul><li>Nella condizione del while , prima è valutato l'assegnamento di getchar a carat , poi il risultato di questa operazione è confrontato con EOF . </li></ul>
  9. 9. Input di caratteri <ul><li>L'esecuzione di questo programma produce uno strano effetto: i caratteri appaiono sullo schermo man mano che sono introdotti; quando poi si preme <RETURN> (“invio”) viene visualizzata di nuovo tutta la riga. </li></ul><ul><li>  </li></ul><ul><li>La giustificazione sta nel fatto che la gestione fisica dell'input, è operata dal Sistema Operativo il quale legge i caratteri provenienti da tastiera, ne fa l' eco sul video e li immagazzina in un vettore interno ( buffer di tastiera ). </li></ul><ul><li>  </li></ul><ul><li>I caratteri introdotti sono trasmessi al programma solo dopo che è stato introdotto un carattere terminatore (come per esempio <RETURN> , ecc.). </li></ul>
  10. 10. Input di caratteri <ul><li>In questo modo si consente all'utente l'eventuale modifica della sequenza dei caratteri già introdotti fino a quando non invia un <RETURN> : questa funzionalità è nota col nome di editing di linea . </li></ul><ul><li>  </li></ul><ul><li>Le procedure interne attivate da scanf e getchar “ aspettano ” che venga introdotto un carattere terminatore (ad esempio “invio”) prima di eseguire le operazioni alle quali sono preposte. </li></ul><ul><li>Pertanto, nel programma precedente, la prima riga è l’effetto dell’eco del sistema operativo, la seconda riga è invece dovuta alla printf posta all’interno del ciclo di lettura </li></ul>
  11. 11. putchar() <ul><li>Visualizzazione di un carattere sul monitor: </li></ul><ul><li>putchar( <carattere> ); </li></ul><ul><li>La funzione di tipo intero putchar prevede un parametro di tipo char , quello appunto che si vuole inviare al video. </li></ul><ul><li>  </li></ul><ul><li>In realtà la definizione in stdio.h rivela che il tipo carattere del parametro viene internamente convertito ad intero. </li></ul><ul><li>  </li></ul><ul><li>Il valore restituito da putchar non è interessante e coincide con il carattere stesso se l'operazione di output ha successo, altrimenti vale EOF .  </li></ul>
  12. 12. Esempio <ul><li>#include <stdio.h> </li></ul><ul><li>  </li></ul><ul><li>main() </li></ul><ul><li>{ </li></ul><ul><li>char carat; </li></ul><ul><li>printf (&quot;Visualizzazione dei caratteri ASCII: &quot;); </li></ul><ul><li>carat = ‘ ’; /* primo carattere ASCII: spazio */ </li></ul><ul><li>while (carat <= ‘ ~ ’) </li></ul><ul><li>{ </li></ul><ul><li>putchar (carat); </li></ul><ul><li>carat++; </li></ul><ul><li>} </li></ul><ul><li>putchar(‘ ’); /* new-line finale */ </li></ul><ul><li>} </li></ul>
  13. 13. Confronto tra le istruzioni di I/O <ul><li>scanf e printf sono “costruite” a partire da getchar e putchar </li></ul><ul><li>scanf e printf sono utili quando è noto il formato ( tipo ) del dato che viene letto. </li></ul><ul><li>getchar e putchar possono essere utili, anche se il loro uso non è molto semplice, quando non è noto il formato. Ad esempio: un testo in cui sono presenti spazi e punteggiatura e che pertanto non è trattabile con semplicità da scanf e printf . </li></ul>
  14. 14. Input di testi <ul><li>Se si deve leggere un testo (inclusi spazi e punteggiatura) la scanf non è utilizzabile e la getchar è scomoda da usare. </li></ul><ul><li>Per introdurre testi il C fornisce un’apposita istruzione, la </li></ul><ul><li>gets ( <stringa> ); </li></ul><ul><li>che legge da tastiera una riga intera, compresi spazi e punteggiatura, fino all’introduzione di <RETURN> (INVIO); </li></ul><ul><li>la sequenza di caratteri letti viene trasmessa al programma sottoforma di stringa in < stringa > , senza il carattere ‘ ’. </li></ul>
  15. 15. Input di testi <ul><li>Poiché come al solito non ci sono controlli sugli indici, la stringa deve essere dichiarata di dimensioni opportune. </li></ul><ul><li>Non è tuttavia possibile limitare il numero di caratteri che l’utente introduce e pertanto si è esposti a eventuali danni causati dal superamento del limite del vettore. </li></ul><ul><li>La < stringa > così introdotta è una stringa a tutti gli effetti: infatti la gets inserisce il carattere di fine stringa NULL (ovvero ‘ ’). </li></ul><ul><li>Pertanto < stringa > può essere normalmente elaborata. </li></ul>
  16. 16. Output di testi <ul><li>Anche per visualizzare testi il C fornisce un’apposita istruzione, la </li></ul><ul><li>puts ( <stringa> ); </li></ul><ul><li>che visualizza sul monitor <stringa> , aggiungendo alla fine della stringa un ‘ ’ . </li></ul><ul><li>L’istruzione </li></ul><ul><li>puts (stringa); </li></ul><ul><li>produce lo stesso output di </li></ul><ul><li>printf (“%s ”, stringa); </li></ul>
  17. 17. I/O di testi - Esempio <ul><li>#include <stdio.h> </li></ul><ul><li>main() </li></ul><ul><li>{ </li></ul><ul><li>char riga[80]; </li></ul><ul><li>printf (“Introduci una riga di testo: ”); </li></ul><ul><li>gets (riga); </li></ul><ul><li>printf (“Hai scritto: ”); </li></ul><ul><li>puts (riga); </li></ul><ul><li>} </li></ul>
  18. 18. sprintf e sscanf <ul><li>Importanti sono anche le due funzioni sprintf e sscanf , che operano come la printf e la scanf , effettuando una conversione pilotata da un format ; la differenza sta nel riferimento: stringa invece di stream (tastiera o monitor). </li></ul><ul><li>  </li></ul><ul><li>La sintassi di sprintf è: </li></ul><ul><li>sprintf ( <stringa>, <format>, <lista variabili> ); </li></ul><ul><li>  </li></ul><ul><li>Genera in <stringa> la stessa sequenza di caratteri che genererebbe la printf sul monitor. Alla fine chiude la stringa appena generata col carattere ‘ ’ (NULL). </li></ul>
  19. 19. sprintf e sscanf <ul><li>Ad esempio, eseguendo il seguente frammento di programma: </li></ul><ul><li>int giorno, mese, anno; </li></ul><ul><li>char data[80]; </li></ul><ul><li>……… </li></ul><ul><li>giorno = 20; </li></ul><ul><li>mese = 5; </li></ul><ul><li>anno = 2009; </li></ul><ul><li>sprintf(data,&quot;Torino %2d-%2d-%4d&quot;, giorno, mese, anno); </li></ul><ul><li>La stringa data sarà formata dalla seguente sequenza di caratteri: </li></ul><ul><li>“ Torino 20- 5-2009 ”. </li></ul>
  20. 20. sprintf e sscanf <ul><li>La sintassi di sscanf è: </li></ul><ul><li>sscanf ( <stringa>, <format>, <lista variabili> ); </li></ul><ul><li>Le variabili della lista vengono lette interpretando i caratteri contenuti in <stringa> secondo le modalità fissate dagli specificatori di formato contenuti nel format . </li></ul><ul><li>  </li></ul><ul><li>Esempio: </li></ul><ul><li>int giorno, mese, anno; </li></ul><ul><li>char luogo[10]; char data[80] = {“Torino 20 5 2009 ”} </li></ul><ul><li>…………………………… .. </li></ul><ul><li>sscanf (data,”%s%d%d%d”, luogo, & giorno, &mese, &anno); </li></ul><ul><li>luogo vale “ Torino ” giorno vale 20 , mese vale 5 e anno vale 2009 . </li></ul>
  21. 21. Dati sulla linea di comando <ul><li>Abbiamo già avuto occasione di osservare come il main sia in realtà una funzione. </li></ul><ul><li>Come le altre funzioni il main è in grado di ricevere dei parametri che devono essere indicati tra le parentesi tonde che seguono la parola chiave main . </li></ul><ul><li>Per introdurre questi parametri occorre scriverli di seguito al nome del programma sulla linea di comando e separati tra loro da spazio. </li></ul><ul><li>Si tratta evidentemente di un’utile alternativa all’introduzione dei dati da tastiera. </li></ul><ul><li>Esempio: </li></ul><ul><li>bmi 72.60 175 </li></ul>
  22. 22. Dati sulla linea di comando <ul><li>I parametri così indicati vengono passati dal sistema operativo al main tramite la seguente coppia di parametri: </li></ul><ul><li>int argc argument counter </li></ul><ul><li>char *argv[] argument vector </li></ul><ul><li>argc è una variabile intera che contiene il numero di parametri contenuti nel vettore di stringhe (matrice di caratteri) argv. </li></ul><ul><li>argv è un vettore di stringhe (matrice di caratteri). </li></ul><ul><li>Queste due variabili devo no essere dichiarate come parametri della funzione main : </li></ul><ul><li>int main (int argc, char *argv[]) </li></ul>
  23. 23. Dati sulla linea di comando <ul><li>argc indica il numero di parametri presenti sulla riga di comando, incluso il nome del programma (pertanto vale sempre almeno 1). </li></ul><ul><li>il vettore argv[ ] (matrice di caratteri) contiene i parametri veri e propri sottoforma di stringhe secondo il seguente formato: </li></ul><ul><ul><li>argv[0] è il nome del programma; </li></ul></ul><ul><ul><li>argv[n] è la stringa che rappresenta l’ ennesimo parametro dopo il nome del programma. </li></ul></ul><ul><li>I parametri pertanto sono sempre delle stringhe : per trasformarli in rappresentazioni numeriche occorre usare le funzioni approppriate ( atoi , atol , atof ) o la sscanf . </li></ul>
  24. 24. Dati sulla linea di comando <ul><li>Struttura </li></ul><ul><ul><li>Esempio: c:> programma.exe 3 pippo.dat 3.2 </li></ul></ul>argc = 4 argv[0] argv[1] argv[2] argv[3] “ programma.exe ” “ 3 ” “ pippo.dat ” “ 3.2 ”
  25. 25. Dati sulla linea di comando <ul><li>Esempio: scrivere un programma che legga sulla linea di comando due interi N e D, e visualizzi tutti i numeri minori di N che sono divisibili per D. </li></ul><ul><li>Il programma dovrà pertanto essere eseguito con il seguente comando: </li></ul><ul><li>myprog N D </li></ul><ul><li>dove myprog è il nome del programma, N e D sono i due valori richiesti per il funzionamento del programma. </li></ul>
  26. 26. Dati sulla linea di comando <ul><ul><li>#include <stdio.h> </li></ul></ul><ul><ul><li>int main(int argc, char *argv[]) </li></ul></ul><ul><ul><li>{ </li></ul></ul><ul><ul><li>int N, D, i; </li></ul></ul><ul><ul><li>if (argc != 3) </li></ul></ul><ul><ul><li>{ </li></ul></ul><ul><ul><li> printf (”Numero argomenti errato Sintassi: myprog N D”); </li></ul></ul><ul><ul><li> return (15); </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>N = atoi (argv[1]); /* converte N */ </li></ul></ul><ul><ul><li>D = atoi (argv[2]); /* converte D */ </li></ul></ul><ul><ul><li>/* oppure: sscanf (argv[1], “%d”, &N */ </li></ul></ul><ul><ul><li>/* sscanf (argv[2], “%d”, &D */ </li></ul></ul><ul><ul><li>for (i = 1; i < N; i++) </li></ul></ul><ul><ul><li>if ((i % D) == 0) printf (”%d ”, i); </li></ul></ul><ul><ul><li>} </li></ul></ul>Test per verificare che l’utente ha introdotto il numero esatto di dati Converte le stringhe nella rappresentazione degli interi (compl. A 2)

×