INFORMATICA Altre Istruzioni di I/O
© Piero Demichelis 2 Funzioni di I/O 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. scanf e printf sono in realtà funzioni di tipo int e, come tali, ritornano un valore intero attraverso il loro nome. La scanf restituisce il numero di parametri letti correttamente: se, ad esempio, la si richiama con un unico parametro (si intende leggere un solo dato), il valore restituito è 1 se la lettura è andata a buon fine, 0 in caso di errore. La printf restituisce invece il numero di bytes che ha inviato in output, oppure 0 in caso di errore.
© Piero Demichelis 3 Funzioni di I/O Nel seguente frammento di programma: int ndati, dato; ndati = scanf (%d, &dato); in ndati verrebbe restituito il valore 1. Nella lettura di dati da tastiera non è previsto alcun codice particolare per segnalare il fatto che i dati in ingresso sono finiti. Generalmente per questo evento si una combinazione particolare di caratteri: ad esempio i tasti CTRL (control) e Z (che il Sistema Operativo interpreta come valore particolare chiamato EOF e definito internamente).
© Piero Demichelis 4 Esempio Programma che calcola il valor medio di un certo numero di dati reali (non noto a priori) terminanti con EOF, introdotti da terminale. #include #define VERO 1 #define FALSO 0 main() { double numero, somma, media; int numdati, stato; int fine_lettura; fine_lettura = FALSO; /* inizializza flag, */
© Piero Demichelis 5 Esempio somma = 0.0; /* accumulatore risultato */ numdati = 0; /* contatore dei dati introdotti */ printf (\nIntroduci i dati (reali), CTRL+Z per finire:\n"); while (!fine_lettura) /* continua fino al CTRL+Z */ { stato = scanf ("%lf", &numero); /* in stato numero dati letti */ if (stato == 1) { somma += numero; /* accumula in somma */ numdati++; /* incrementa numdati (dati letti correttamente) */ } else fine_lettura = VERO; /* fine lettura */ } /* fine di while NOT fine_lettura */
© Piero Demichelis 6 Esempio if (numdati == 0) printf (\nMedia non calcolabile"); else { media = somma / numdati; printf (\nLa media su %d dati e': %lf", numdati, media); } 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.
© Piero Demichelis 7 getchar() Lettura di un carattere da tastiera: getchar(); La funzione senza parametri getchar è definita in stdio.h di tipo intero (int) e restituisce un numero intero corrispondente al codice del tasto premuto. 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. Se si esclude il caso dell'EOF è lecito assegnare il valore fornito da questa funzione ad una variabile di tipo carattere (char).
© Piero Demichelis 8 Esempio #include int carat; main() { printf (\nInserisci dei caratteri, CTRL+Z per finire\n "); while ( ( carat = getchar() ) != EOF) printf ("%c", carat); } Nella condizione del while, prima è valutato l'assegnamento di getchar a carat, poi il risultato di questa operazione è confrontato con EOF.
© Piero Demichelis 9 Input di caratteri L'esecuzione di questo programma produce uno strano effetto: i caratteri appaiono sullo schermo man mano che sono introdotti; quando poi si preme (invio) viene visualizzata di nuovo tutta la riga. 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). I caratteri introdotti sono trasmessi al programma solo dopo che è stato introdotto un carattere terminatore (come per esempio, ecc.).
© Piero Demichelis 10 Input di caratteri In questo modo si consente all'utente l'eventuale modifica della sequenza dei caratteri già introdotti fino a quando non invia un : questa funzionalità è nota col nome di editing di linea. I caratteri, + Z, + C, costituiscono eventi significativi di tastiera. Le procedure interne attivate da scanf e getcharaspettano che ci sia un evento significativo prima di eseguire le operazioni alle quali sono preposte.
© Piero Demichelis 11 putchar() Visualizzazione di un carattere sul monitor: putchar( ); La funzione di tipo intero putchar prevede un parametro di tipo char, quello appunto che si vuole inviare al video. In realtà la definizione in stdio.h rivela che il tipo carattere del parametro viene internamente convertito ad intero. Il valore restituito da putchar coincide con il carattere stesso se l'operazione di output ha successo, altrimenti vale EOF.
© Piero Demichelis 12 Esempio #include char carat; main() { printf (\nVisualizzazione dei caratteri ASCII:\n "); carat = ; while (carat <= ~ ) { putchar (carat); carat++; } putchar ( \n ); /* new-line finale */ }
© Piero Demichelis 13 Confronto tra le istruzioni di I/O scanf e printf sono costruite a partire da getchar/putchar scanf/printf sono utili quando è noto il formato (tipo) del dato che viene letto. getchar/putchar sono utili 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.
© Piero Demichelis 14 Input di testi Se si deve leggere un testo (inclusi spazi e punteggiatura) la scanf non è utilizzabile e la getchar è scomoda da usare. Per introdurre testi il C fornisce unapposita istruzione, la gets ( ); che legge da tastiera una riga intera, compresi spazi e punteggiatura, fino allintroduzione di (INVIO); la sequenza di caratteri letti viene trasmessa al programma sottoforma di stringa in, senza il carattere \n.
© Piero Demichelis 15 Input di testi Poiché come al solito non ci sono controlli sugli indici, la stringa deve essere dimensionata opportunamente. Non è tuttavia possibile limitare il numero di caratteri che lutente introduce e pertanto si è esposti a eventuali danni causati dal travalicamento dei limiti. La così introdotta è una stringa a tutti gli effetti: infatti la gets inserisce il carattere di fine stringa NULL (ovvero \0). Pertanto può essere normalmente elaborata.
© Piero Demichelis 16 Output di testi Anche per visualizzare testi il C fornisce unapposita istruzione, la puts ( ); che visualizza sul monitor, aggiungendo alla fine della stringa un \n. Listruzione puts (stringa); produce lo stesso output di printf (%s\n, stringa);
© Piero Demichelis 17 I/O di testi - Esempio #include main() { char riga[80]; printf (\nIntroduci una riga di testo:\n); gets (riga); printf (\nHai scritto:\n); puts (riga); }
© Piero Demichelis 18 sprintf e sscanf 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). La sintassi di sprintf è: sprintf (,, ); Genera in la stessa sequenza di caratteri che genererebbe la printf sul monitor. Alla fine chiude la stringa appena generata col carattere \0 (NULL).
© Piero Demichelis 19 sprintf e sscanf Ad esempio, eseguendo il seguente frammento di programma: int giorno, mese, anno; char data[80]; ……… giorno = 12; mese = 2; anno = 2005; sprintf (data,"Torino %2d-%2d-%4d", giorno, mese, anno); La stringa data sarà formata dalla seguente sequenza di caratteri: Torino \0.
© Piero Demichelis 20 sprintf e sscanf La sintassi di sscanf è: sscanf (,, ); Le variabili della lista vengono lette interpretando i caratteri contenuti in secondo le modalità fissate dagli specificatori di formato contenuti nel format. Esempio: int giorno, mese, anno; char data[10] = {2, 0,, 7,, 2, 0, 0, 5, \0} ……..; sscanf (data,%d%d%d, &giorno, &mese, &anno); giorno vale 20, mese vale 7 e anno vale 2005.