Università dell’Insubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea in Informatica Anno Accademico 2007/08 Laboratorio di Linguaggi lezione XI: I/O Marco Tarini Input / Output Input / Output Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Printf • Scrittura formattata int printf( const char* formato [, lista parametri...] ) Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Input / Output • Scrittura formattata carattere '\n': End Of Line (accapo) int x=10; ... printf("Il valore di x e' %d \n", x); %d è un format tag : • Scrive sullo schermo: significa, scrivi il valore di un parametro intero Il valore di x e' 10 Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Input / Output • Scrittura formattata int x=10, y=0; ... printf("Posizione [%d,%d] ! ", x, y); • Scrive sullo schermo: Posizione [10,0] ! Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria 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 ! Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Format Tags • Il format tag definisce – come interpretare – con che formato scrivere il parametro corrispondente format tag: interpreta il parametro come: un intero con segno %d %i %u %x %X %f %e %E %o un intero senza segno un numero in virgola mobile %c un carattere %s una stringa %p un puntatore Marco Tarini - Laboratorio di Linguaggi - un array di caratteri terminato da '\0' 2007/08 - Università dell’Insubria Format Tags • Il format tag definisce – come interpretare – con che formato scrivere il parametro corrispondente format tag: un intero con segno %d %i %u %x %X %f %e %E %c %s %p interpreta il parametro come: %o un intero senza segno un numero in virgola mobile in base otto (es. 16473 ) un carattere in esadecimale (es. 12AC3A ) stringa inuna esadecimale (es. 12ac3a ) puntatore inun decimale Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Format Tags • Il format tag definisce – come interpretare – con che formato scrivere il parametro corrispondente format tag: un intero con segno %d %i %#u %#x %#X %f %e %E %c %s %p interpreta il parametro come: %#o un intero senza segno un numero in virgola mobile in base otto (es. 016473 ) un carattere in esadecimale (es. 0X12AC3A ) stringa inuna esadecimale (es. 0x12ac3a ) puntatore inun decimale Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Format Tags • Il format tag definisce – come interpretare – con che formato scrivere il parametro corrispondente format tag: %d %i %f %e %c %s %p interpreta il parametro come: un intero con segno %E un numero in virgola mobile in notazione esponenziale un carattere (es. 1.2e12 ) una1.2E12 stringa ) (es. puntatorecomune inun notazione Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Format Tags • Esempio printf("Scrivo %d %d e %d !\n\nah!\n", 1, 2, 3); • Risultato: Scrivo 1 2 e 3 ah! Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Format Tags • Esempio printf("Scrivo %5d %5d e %5d !\n\nah!\n", 1, 2, 3); "5 caratteri di lunghezza" • Risultato: Scrivo 1 2 e 3 ah! Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Format Tags • etc... +: specifica il segno l: è un "float lungo", cioè un double anche se pos printf("Scrivo: %+6.3lf 6 cifre in tutto e anche %+.0e\n", 1.1, 1.2 ); 3 cifre dopo virgola • Risultato: Scrivo: +1.100 e anche +1e+000 Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Format Tags • etc... char* stringa= "Totale (in euro): "; int res; ... printf("%s%d\n", stringa , res ); • Risultato: Totale (in euro): 130 Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria 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). Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Format Tags • Avvertenza: attenzione ai tipi printf("Torna %f euro\n", 150 ); • Sullo schermo: Torna 0 euro Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Format Tags • Avvertenza: attenzione ai tipi int x=150; printf("Torna %f euro\n", x ); • Sullo schermo: Torna 0 euro Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Funzionamento di printf • Come si scrive un programma che ci dice quale e' il codice ascii del simbolo '!'? • E se lo vogliamo in esadecimale? Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria 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 Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria 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 Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Scrivere non solo sullo schermo int printf( const char* format [, lista param.] printf: scrive sull'output standard ) int fprintf( FILE* stream, const char* format [, lista param.] ) int sprintf( char* output, const char* format [, lista param.] ) fprintf: scrive su un File sprintf: scrive su un'altra Stringa Marco Tarini - Laboratorio di Linguaggi - (che deve essere già allocata) 2007/08 - Università dell’Insubria 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?! Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Esempio con fprintf • scrittura in un file 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- read o write o append , 2- modo testo o binario • Restituisce NULL se non è riusicto ad aprire il 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); 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 Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Input / Output Input / Output Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria scanf • da printf a scanf – per leggere dalla tastiera invece che scrivere sul monitor int x; ... printf("%d", scanf & x); 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) Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria 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", n n n &x, &y, &z); sarà uguale a 3 se l'utente avrà digitato, ad esempio: 5-5:A0A111 sarà uguale a 2 se l'utente avrà digitato, ad esempio: 5-5pippo sarà uguale a 0 se l'utente avrà digitato, ad esempio: >:-P Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria 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 ); Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Leggere non solo dalla tastiera int scanf( const char* format [, lista punt.] scanf: legge dall'input standard ) int fscanf( FILE* stream, const char* format [, lista punt.] ) int sscanf( char* input, const char* format [, lista punt.] ) fscanf: legge da un File sscanf: legge da una Stringa Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Esempio di fscanf 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* file_di_input= fopen ("ciao.txt", "rt"); fscanf( file_di_input,"(%f %f %f)",&x,&y,&z ); fclose(file_di_input); Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Input Output output da/a terminale input printf scanf da/a stringhe sprintf sscanf da/a files fprintf fscanf Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Uso tipico di sscanf : • Lettura degli argomenti da riga di comando di un programma. numero di argomenti + 1 argv[0] : nome del programma argv[1] : primo argomento ... argv[argc-1] : ultimo argomento int main(int argc, char *argv[]) argv[1] argv[0] argv[2] C:> pippo.exe –a –o:zap Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Per provare il programma su Dev-C++ • Impostare gli argomenti su Dev-C++ 21| Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria 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: 00 00 00 01 */ ... return 1; } Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Input Output output da/a terminale input printf scanf da/a stringhe sprintf sscanf da/a files fprintf fscanf Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria 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); Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria 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) Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Gestione files • Scrittura e lettura non formattate fwrite o fread ( 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 Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Gestione files • tutte le funzioni per leggere e scrivere su files... fwrite fprintf fread fscanf • leggono e scrivono dalla posizione corrente – che viene aggiornata come effetto collaterale Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria Gestione files • la posizione corrente: – e' un long int – puo' essere letta long int ftell(FILE *fp); – puo' essere cambiata: 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 ); – o anche, riportata all'inizio del file: int rewind (FILE *fp ); Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubria