INFORMATICA Altre Istruzioni di IO Funzioni di IO

  • Slides: 20
Download presentation
INFORMATICA Altre Istruzioni di I/O

INFORMATICA Altre Istruzioni di I/O

Funzioni di I/O • Per la lettura e la scrittura da videoterminale il C

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 2

Funzioni di I/O • Nel seguente frammento di programma: int ndati, dato; . .

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 3

Esempio • Programma che calcola il valor medio di un certo numero di dati

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 <stdio. h> #define VERO 1 #define FALSO 0 main() { double numero, somma, media; int numdati, stato; int fine_lettura; fine_lettura = FALSO; /* inizializza flag, */ © Piero Demichelis 4

Esempio somma = 0. 0; numdati = 0; /* accumulatore risultato */ /* contatore

Esempio somma = 0. 0; numdati = 0; /* accumulatore risultato */ /* contatore dei dati introdotti */ printf (“n. Introduci 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 5

Esempio if (numdati == 0) printf (“n. Media non calcolabile"); else { media =

Esempio if (numdati == 0) printf (“n. Media non calcolabile"); else { media = somma / numdati; printf (“n. La 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 6

getchar() • Lettura di un carattere da tastiera: getchar(); • La funzione senza parametri

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 7

Esempio #include <stdio. h> int carat; main() { printf (“n. Inserisci dei caratteri, CTRL+Z

Esempio #include <stdio. h> int carat; main() { printf (“n. Inserisci dei caratteri, CTRL+Z per finiren "); 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 8

Input di caratteri • L'esecuzione di questo programma produce uno strano effetto: i caratteri

Input di caratteri • L'esecuzione di questo programma produce uno strano effetto: i caratteri appaiono sullo schermo mano che sono introdotti; quando poi si preme <RETURN> (“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 <RETURN>, ecc. ). © Piero Demichelis 9

Input di caratteri • In questo modo si consente all'utente l'eventuale modifica della sequenza

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 <RETURN>: questa funzionalità è nota col nome di editing di linea. • I caratteri <RETURN>, <CONTROL>+ Z, <CONTROL>+ C, <BREAK> costituiscono “eventi significativi ” di tastiera. • Le procedure interne attivate da scanf e getchar “aspettano ” che ci sia un “evento significativo ” prima di eseguire le operazioni alle quali sono preposte. © Piero Demichelis 10

putchar() • Visualizzazione di un carattere sul monitor: putchar(<carattere>); • La funzione di tipo

putchar() • Visualizzazione di un carattere sul monitor: putchar(<carattere>); • 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 11

Esempio #include <stdio. h> char carat; main() { printf (“n. Visualizzazione dei caratteri ASCII:

Esempio #include <stdio. h> char carat; main() { printf (“n. Visualizzazione dei caratteri ASCII: n "); carat = ‘ ’; while (carat <= ‘ ~ ’) { putchar (carat); carat++; } putchar (‘ n ’); /* new-line finale } © Piero Demichelis */ 12

Confronto tra le istruzioni di I/O • scanf e printf sono “costruite” a partire

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 13

Input di testi • Se si deve leggere un testo (inclusi spazi e punteggiatura)

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 un’apposita istruzione, la gets (<stringa>); che legge da tastiera una riga intera, compresi spazi e punteggiatura, fino all’introduzione di <RETURN> (INVIO); • la sequenza di caratteri letti viene trasmessa al programma sottoforma di stringa in <stringa>, senza il carattere ‘n’. © Piero Demichelis 14

Input di testi • Poiché come al solito non ci sono controlli sugli indici,

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 l’utente introduce e pertanto si è esposti a eventuali danni causati dal travalicamento dei limiti. • La <stringa> così introdotta è una stringa a tutti gli effetti: infatti la gets inserisce il carattere di fine stringa NULL (ovvero ‘’). • Pertanto <stringa> può essere normalmente elaborata. © Piero Demichelis 15

Output di testi • Anche per visualizzare testi il C fornisce un’apposita istruzione, la

Output di testi • Anche per visualizzare testi il C fornisce un’apposita istruzione, la puts ( <stringa> ); che visualizza sul monitor <stringa>, aggiungendo alla fine della stringa un ‘n’. • L’istruzione puts (stringa); produce lo stesso output di printf (“%sn”, stringa); © Piero Demichelis 16

I/O di testi - Esempio #include <stdio. h> main() { char riga[80]; printf (“n.

I/O di testi - Esempio #include <stdio. h> main() { char riga[80]; printf (“n. Introduci una riga di testo: n”); gets (riga); printf (“n. Hai scritto: n”); puts (riga); } © Piero Demichelis 17

sprintf e sscanf • Importanti sono anche le due funzioni sprintf e sscanf, che

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 (<stringa>, <format>, <lista variabili>); • Genera in <stringa> la stessa sequenza di caratteri che genererebbe la printf sul monitor. Alla fine chiude la stringa appena generata col carattere ‘’ (NULL). © Piero Demichelis 18

sprintf e sscanf • Ad esempio, eseguendo il seguente frammento di programma: int giorno,

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 %2 d-%4 d", giorno, mese, anno); • La stringa data sarà formata dalla seguente sequenza di caratteri: “Torino 12 - 2 -2005”. © Piero Demichelis 19

sprintf e sscanf La sintassi di sscanf è: sscanf (<stringa>, <format>, <lista variabili>); •

sprintf e sscanf La sintassi di sscanf è: sscanf (<stringa>, <format>, <lista variabili>); • Le variabili della lista vengono lette interpretando i caratteri contenuti in <stringa> secondo le modalità fissate dagli specificatori di formato contenuti nel format. Esempio: int giorno, mese, anno; char data[10] = {‘ 2’, ‘ 0’, ‘ 7’, ‘ 2’, ‘ 0’, ‘ 5’, ‘’} ……. . ; sscanf (data, ”%d%d%d”, &giorno, &mese, &anno); • giorno vale 20, mese vale 7 e anno vale 2005. © Piero Demichelis 20