Laboratorio di Linguaggi lezione XI: I/O Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea in Informatica Anno Accademico 2007/08
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Input / Output
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Printf Scrittura formattata int printf( const char* formato [, lista parametri...] )
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Input / Output Scrittura formattata int x=10;... printf("Il valore di x e' %d \n", x); Scrive sullo schermo: Il valore di x e' 10 carattere '\n' : End Of Line (accapo) %d è un format tag : significa, scrivi il valore di un parametro intero
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Input / Output Scrittura formattata int x=10, y=0;... printf("Posizione [%d,%d] ! ", x, y); Scrive sullo schermo: Posizione [10,0] !
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Format Tags Vi ricordate che 'a' e 121 sono entrambi costanti (literals) di tipo char ? Usando il format tag appropriato, posso far scrivere uno o l'altro: char ch='a';... printf("Posso scrivere %c o %d a piacare ! ", ch, ch); Scrive sullo schermo: Posso scrivere a o 96 a piacere !
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Format Tags Il format tag definisce –come interpretare –con che formato scrivere il parametro corrispondente un array di caratteri terminato da '\0' %i%d %u%x%X %c %f%e%E %p format tag: interpreta il parametro come: un intero con segno un intero senza segno un numero in virgola mobile un carattere una stringa un puntatore %s %o
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a %i%d %u%x%X %c %f%e%E %p format tag: interpreta il parametro come: un intero con segno un intero senza segno un numero in virgola mobile un carattere una stringa un puntatore %s %o Format Tags Il format tag definisce –come interpretare –con che formato scrivere il parametro corrispondente in decimale in esadecimale (es. 12ac3a ) in esadecimale (es. 12AC3A ) in base otto (es )
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a %i%d %#u%#u%#x%#X %c %f%e%E %p format tag: interpreta il parametro come: un intero con segno un intero senza segno un numero in virgola mobile un carattere una stringa un puntatore %s %#o Format Tags Il format tag definisce –come interpretare –con che formato scrivere il parametro corrispondente in decimale in esadecimale (es. 0x12ac3a ) in esadecimale (es. 0X12AC3A ) in base otto (es )
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a %i%d %c %f%e%E %p format tag: interpreta il parametro come: un intero con segno un numero in virgola mobile un carattere una stringa un puntatore %s Format Tags Il format tag definisce –come interpretare –con che formato scrivere il parametro corrispondente in notazione comune (es. 1.2E12 ) in notazione esponenziale (es. 1.2e12 )
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Format Tags Esempio printf("Scrivo %d %d e %d !\n\nah!\n", 1, 2, 3); Risultato: Scrivo 1 2 e 3 ah!
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Risultato: Scrivo 1 2 e 3 ah! Format Tags Esempio printf("Scrivo %5d %5d e %5d !\n\nah!\n", 1, 2, 3); "5 caratteri di lunghezza"
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Risultato: Scrivo: e anche +1e+000 Format Tags etc... printf("Scrivo: %+6.3lf e anche %+.0e\n", 1.1, 1.2 ); 6 cifre in tutto 3 cifre dopo virgola l : è un "float lungo", cioè un double + : specifica il segno anche se pos
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Risultato: Totale (in euro): 130 Format Tags etc... char* stringa= "Totale (in euro): "; int res;... printf("%s%d\n", stringa, res );
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Format Tags Avvertenza: attenzione ai tipi printf("Torna %f euro\n", 150 ); Sullo schermo: Torna 0 euro Errore! Ha interpretato un valore intero come un float! Se i due tipi hanno dimensione diversa, può anche causare un crash (errore di accesso in lettura).
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Format Tags Avvertenza: attenzione ai tipi printf("Torna %f euro\n", 150 ); Sullo schermo: Torna 0 euro
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Format Tags Avvertenza: attenzione ai tipi int x=150; printf("Torna %f euro\n", x ); Sullo schermo: Torna 0 euro
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Funzionamento di printf Come si scrive un programma che ci dice quale e' il codice ascii del simbolo '!' ? E se lo vogliamo in esadecimale?
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Funzionamento di printf Come si scrive un programma che risolve il quiz del banner misterioso? char msg[]= {78,111,119,32,72,105,110,103,0}; testo del quiz
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Dove scrive printf? sull' output standard di solito, significa sul monitor ma, ad esempio... –al momento di eseguire il programma posso utilizzare il la sintassi: programma > file
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Scrivere non solo sullo schermo int printf( const char* format [, lista param.] ) printf : scrive sull'output standard int fprintf( const char* format [, lista param.] ) fprintf : scrive su un File int sprintf( const char* format [, lista param.] ) sprintf : scrive su un'altra Stringa (che deve essere già allocata) FILE* stream, char* output,
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Esempio con sprintf concatenazione di stringhe char[] stringa1 = "cacio"; char[] stringa2 = "cavallo"; char *concat; sprintf(concat,"%s%s",stringa1, stringa2); NON vi eravate accorti dell'errore?!
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Esempio con fprintf scrittura in un file float x,y,z; FILE* file_di_output= fopen ("ciao.txt", "wt"); fprintf( file_di_output,"(%f %f %f)",x,y,z ); fclose(file_di_output); FILE* : il puntatore a una struttura che contiene tutto quello che c'è da sapere su un file aperto. Cosa contiene questa struttura? Non importa! (è platform dependent) Gestiamo i file utilizzando solo puntatori a questa struttura... fopen : apri un file. resitutisce un FILE* (alloca la struttura & apre il file) Primo parametro: nome del file Secondo parametro: stringa con 1- r ead o w rite o a ppend, 2- modo t esto o b inario Restituisce NULL se non è riusicto ad aprire il file fclose : chiudi un file. (chiude il file & disalloca la struttura) solo un certo numero di files può essere aperto in un dato momento consente ad altre applicazioni di usare il file
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Input / Output
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a scanf da printf a scanf –per leggere dalla tastiera invece che scrivere sul monitor int x;... printf("%d", x); scanf & ora vuole un puntatori! (perche?) deve essere un puntatore a qualcosa di allocato (in questo esempio, è allocato automaticamente) e' ancora + importante che il tipo del puntatore corrisponda al format tag! (errori in scrittura invece che lettura, fa più male)
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a scanf Tutto il resto come printf Restituisce il numero di target tag che è stato corettamente assegnato int x,y, n; unsigned int z;... n = scanf("%d-%d:%X", &x, &y, &z); n sarà uguale a 3 se l'utente avrà digitato, ad esempio: 5-5:A0A111 n sarà uguale a 2 se l'utente avrà digitato, ad esempio: 5-5pippo n sarà uguale a 0 se l'utente avrà digitato, ad esempio: >:-P
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a scanf Tutto il resto come printf Restituisce il numero di target tag che è stato corettamente assegnato int g,m,a; do { printf("inserisci giorno/mese/anno:" ); } while ( scanf("%u/%u/%u", &g, &m, &a)!=3 );
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Leggere non solo dalla tastiera int scanf( const char* format [, lista punt.] ) scanf : legge dall'input standard int fscanf( const char* format [, lista punt.] ) fscanf : legge da un File int sscanf( const char* format [, lista punt.] ) sscanf : legge da una Stringa FILE* stream, char* input,
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Esempio di fscanf FILE* file_di_output= fopen ("ciao.txt", "wt"); fprintf( file_di_output,"(%f %f %f)",x,y,z ); fclose(file_di_output); FILE* file_di_input= fopen ("ciao.txt", "rt"); fscanf( file_di_input,"(%f %f %f)",&x,&y,&z ); fclose(file_di_input); float x,y,z;
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Input Output printf sprintf fprintf scanf sscanf fscanf da/a terminale da/a stringhe da/a files inputoutput
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Uso tipico di sscanf : Lettura degli argomenti da riga di comando di un programma. int main(int argc, char *argv[]) argv[0] : nome del programma argv[1] : primo argomento... argv[argc-1] : ultimo argomento numero di argomenti + 1 C:> pippo.exe –a –o:zap argv[0] argv[1] argv[2]
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Per provare il programma su Dev-C++ Impostare gli argomenti su Dev-C++ 21|
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Uso tipico di sscanf (compito per casa) : /* mostra le isturzioni di uso da riga di comando */ void show_usage(){... } int main(int argc, char *argv[]) { int x; if (argc<2) { /* nessun argomento: mostra l'aiuto e esci */ show_usage(); return 0; } if (sprintf("%d", argv[1], &x) != 1) { /* il primo argomento non e' un numero: mostra l'aiuto e esci */ show_usage(); return 0; } /* mostra i byte che compongono il numero... in base 16. Due cifre a byte, separate da uno spazio es: */... return 1; }
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Input Output printf sprintf fprintf scanf sscanf fscanf da/a terminale da/a stringhe da/a files inputoutput
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Gestione files FILE* file_di_output= fopen ("ciao.txt", "wt");... /* uso il file in scrittura */ fclose(file_di_output); FILE* file_di_output= fopen ("ciao.txt", "rt");... /* uso il file in lettura */ fclose(file_di_output);
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Files in binario o in modo testo? Binario: –veloce –platform dependent incubi di compatibilità se si leggono files scritti con una architettura differente –di solito più coinciso Modo testo: –più lento –platform independent –file comprensibili (leggibili in "umano" come testo)
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Gestione files Scrittura e lettura non formattate fwrite fread o ( void* p, int size_elem, int n_elem, FILE* f) scrivono/leggono (in binario) sul file restituiscono il numero di elementi scritti/letti sono operatori efficienti
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Gestione files tutte le funzioni per leggere e scrivere su files... leggono e scrivono dalla posizione corrente –che viene aggiornata come effetto collaterale fwrite fread fprintf fscanf
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Gestione files la posizione corrente: –e' un long int –puo' essere letta –puo' essere cambiata: –o anche, riportata all'inizio del file: long int ftell(FILE *fp); int fseek(FILE *fp, long int offset, SEEK_SET ); int fseek(FILE *fp, long int offset, SEEK_CUR ); int fseek(FILE *fp, long int offset, SEEK_END ); int rewind (FILE *fp );