Il linguaggio Fortran 90:
5. Formato di I/O e Files
1
Formati di I/O
• READ (*,*) WRITE (*,*) : formato libero di output
• Si può specificare sia l’unita di I/O che il formato dell’I/O
• REAL :: x
INTEGER :: i
WRITE (*,100) i , x
100 FORMAT (1X, I10, F10.2)
• Risultato formattato:
10
20.40
• Risultato non formattato:
10 20.403456
2
Caratteri di controllo
• Il Fortran utilizza il primo carattere di stampa
come carattere di controllo.
1
Stampa all’inizio di una nuova pagina
spazio
Interlinea singola
0
Interlinea doppia
+
Nessuna interlinea, stampa sulla stessa
riga
• Occorre quindi aggiungere sempre un carattere
all’inizio dell’istruzione di Format.
3
Descrittori di formato
• Descrittore I : rIw.m
I: rappresentazione di valori interi
r: fattore di ripetizione
w: numero massimo di cifre da visualizzare
m: numero minimo di cifre da visualizzare
• Se il valore e’ troppo grande per essere
visualizzato con un certo formato vengono
stampati asterischi
• I valori sono allineati a destra nei loro campi
4
Esempio
INTEGER :: index = -12, junk = 4, number = -12345
WRITE(*,200) index, index + 12, junk, number
WRITE(*,210) index, index + 12, junk, number
WRITE(*,220) index, index + 12, junk, number
200 FORMAT (1X, 2I5, I6, I10)
210 FORMAT (1X, 2I5.0, I6, I10.8)
220 FORMAT (1X, 2I5.3, I6, I5)
||-12||||0|||||4||||-12345
||-12||||||||||4|-00012345
|-012||000|||||4*****
5
Descrittori di formato (cont.)
• rFw.d
F: descrittore di tipo di dato reale
d: numero di cifre a destra del punto decimale
• rEw.d
E: descrittore di notazione esponenziale
I valori sono rappresentati con una mantissa
compresa tra 0.1 e 1.
Ex: 8600.6
0.86006E+4
6
Descrittori di formato (cont.)
• rLw
L: Descrittore di formato logico
I valori logici vengono stampati come T e F
LOGICAL :: a = .TRUE., b = .FALSE.
WRITE (*,200) a,b
200 FORMAT(‘ ‘, 2L5)
||||T||||F
7
Descrittori di formato (cont.)
• nX : inserisce n spazi nel buffer
permette di controllare la spaziatura nel
formato di output
• Tc : permettere di raggiungere la colonna c
• / : chiude il buffer corrente ed apre un
nuovo buffer, va a riga nuova
8
Stampa di una matrice di reali in forma
tabellare
Si intende stampare una matrice di reali con
i valori sulla stessa colonna allineati sulla
destra
-0.34
8.98
10.00
23.45
3.55
1.10
9
Stampa di una matrice di reali in forma
tabellare
SUBROUTINE stampa_matrice2 (a, n, m)
!Scopo: Stampa di una matrice in forma tabellare
! Dichiarazione paramentri formali
IMPLICIT NONE
INTEGER, INTENT(IN) :: n,m
REAL, DIMENSION(:,:), INTENT(IN) :: a
!Dichiarazione variabili locali
INTEGER :: i,j
DO i = 1, n
WRITE (*,100) (a(i,j), j=1,m)
END DO
100 FORMAT (' ', 8F8.2)
STOP
END SUBROUTINE stampa_matrice2
•
•
Assumiamo la linea di stampa del terminale formata di 80 caratteri
Se m > 8, la stampa prosegue con stesso formato alla linea
successiva
10
READ Formattante
• Determina le modalità con cui i dati vengono letti
dal buffer di input.
• Specifica l’associazione tra le posizioni dei dati
nel buffer di input e le variabili in lettura in una
singola istruzione READ
READ (*,100) incremento
100 FORMAT (6X, I6)
Salta le prime 6 colonne e registra in incremento
l’intero letto da colonna 7 a colonna 12.
11
Descrittori di Formato di Input
• Descrittori Standard I, F, L
• Descrittore A
rA: legge i caratteri in un campo di
lunghezza pari alla variabile carattere
rAw: legge i caratteri per una lunghezza pari
aw
12
Elaborazione dei File
• I dati registrati in memoria centrale sono persi al
termine dell’esecuzione dell’applicazione.
• I File sono dispositivi di memorizzazione
permanente dei dati su supporto magnetico oppure
ottico.
• I file possono essere indicati come unità di I/O
all’interno di un’applicazione
• L’unità di I/O viene specificata con un numero
intero al posto del primo * nella prima posizione
di una READ o di una WRITE.
13
Apertura e Chiusura di File
• Il numero di unità è associato ad un file attraverso
l’istruzione OPEN.
• L’istruzione CLOSE annulla l’effetto della OPEN.
• Quando il file è aperto, possiamo leggere o
scrivere sul file con le stesse modalità di un buffer
di Input o di Output.
• Alcuni numeri di unità sono riservati, in genere 5
per lo standard input, 6 per lo standard output.
14
Istruzione OPEN
• OPEN (lista_open)
• lista_open:
–
–
–
–
–
UNIT =
FILE =
STATUS
ACTION
IOSTAT
espr_int
espr_caratt
= espr_caratt
= espr_caratt
= var_int
• Specificano, numero unità, nome e modalità di
accesso al file
15
Istruzione OPEN (cont.)
• UNIT = espr_int: indica il numero
dell’unità
• FILE = espr_caratt: specifica il
nome dell’unità da aprire
• STATUS = espr_caratt: specifica lo
stato dell’unità da aprire, ‘OLD’, ‘NEW’,
‘REPLACE’, ‘SCRATCH’ o ‘UNKNOWN’
16
Istruzione OPEN (cont.)
• ACTION = espr_caratt: specifica
se il file deve essere aperto solo in lettura,
in scrittura o entrampi le modalità, ‘READ’,
‘WRITE’ o ‘READWRITE’
• IOSTAT = var_int: se OPEN ha
successo allora la variabile è 0, altrimenti
ritorna un codice di errore
17
Istruzione OPEN (cont.)
• Ex: File di Input.
INTEGER :: ierror
OPEN (UNIT = 8, FILE = ‘ESEMPIO.DAT’,
STATUS = ‘OLD’, ACTION = ‘READ’, IOSTAT
= ierror)
OLD: file già esistente
READ: file di sola lettura, operazioni di
scrittura restituiscono errore
18
Istruzione OPEN (cont.)
•
INTEGER :: unit, ierror
CHARACTER (len = 6) :: nomefile
unit = 25
Nome_file = ‘OUTDAT’
OPEN (UNIT = unit, FILE = nome_file, STATUS
= ‘NEW’, ACTION = ‘WRITE’, IOSTAT = ierror)
NEW: il file non esiste precedentemente
•
OPEN (UNIT = unit, FILE = nome_file, STATUS
= ‘REPLACE’, ACTION = ‘WRITE’, IOSTAT =
ierror)
REPLACE: il file se esiste viene sostituito
19
Istruzione OPEN (cont.)
• OPEN (UNIT = unit, FILE = nome_file,
STATUS = ‘SCRATCH’, ACTION =
‘READWRITE’, IOSTAT = ierror)
SCRATCH: il file viene aperto durante
l’esecuzione del programma ed eliminato
al termine. Serve per memorizzare
risultati temporanei.
20
Istruzione CLOSE
• CLOSE (lista_close)
• Libera l’associazione tra numero di unità e
file. Il file puo’ essere riaperto se non
SCRATCH anche con un diverso numero di
unità.
• lista_close indica il numero dell’unità
da chiudere
21
Somma degli elementi di un File
! File: sommafil.for
! Scopo: primo esempio di uso di file in sola lettura
PROGRAM somma_file
! Questo programma legge un file che contiene numeri interi e ne
! calcola la somma. Il file ha nome fisico 'dati.txt‘
! Su ogni riga di ‘dati.txt’ viene letto un solo intero.
! *** SEZIONE DICHIARATIVA *** !
IMPLICIT NONE
CHARACTER(12), PARAMETER :: nome_file = 'dati.txt'
INTEGER :: dato
! il dato letto di volta in volta
INTEGER :: quanti = 0
! contatore degli interi letti
INTEGER :: somma = 0
! somma degli interi letti
INTEGER :: istatus
! stato I/O
22
Somma degli elementi di un File (cont.)
! apertura del file in sola lettura
WRITE(*,*) 'Leggo dal file ', nome_file
OPEN (UNIT = 9, FILE = nome_file, STATUS = 'OLD', ACTION = &
'READ',IOSTAT = istatus)
IF (istatus == 0) THEN
! il file e' stato aperto correttamente
DO
READ (9,*,IOSTAT = istatus) dato
! lettura di un dato da file
IF (istatus /= 0) EXIT
! si esce quando il file e' terminato
WRITE(*,*) dato
quanti = quanti + 1
somma = somma + dato
END DO
WRITE(*,*) 'Il file e'' composto di ', quanti, ' dati'
WRITE(*,*) 'La somma dei dati vale ', somma
ELSE
! il file non e' stato aperto correttamente
WRITE(*,*) 'Il file ', nome_file, 'non esiste'
END IF
STOP
END PROGRAM somma_file
23
Calcolo del numero di caratteri in un file
! File: conta.for
! Scopo: altro esempio di uso di file in sola lettura
PROGRAM leggi_file
! Questo programma legge un file di testo e conta di quanti caratteri e
! quante linee e' composto. Il file ha nome fisico 'input.txt'
! Il programma legge una riga del file per ogni iterazione,
! immagazzinandola in una stringa di lunghezza fissata (240).
! Vengono usati alcuni aspetti peculiari delle stringhe:
! - lettura formattata con descrittore di formato A (legge tutta la
!
linea)
! - funzione intrinseca LEN_TRIM(s), che restituisce la lunghezza della
!
stringa s meno gli spazi vuoti finali
! *** SEZIONE DICHIARATIVA *** !
IMPLICIT NONE
CHARACTER(12), PARAMETER :: nome_file
INTEGER, PARAMETER :: lunghezza_linea
CHARACTER(lunghezza_linea) :: linea !
INTEGER :: linee = 0
!
INTEGER :: caratteri = 0
!
INTEGER :: istatus
= 'input.txt'
= 240
la linea letta di volta in volta
contatore delle linee lette
contatore dei caratteri letti
24
Calcolo del numero di caratteri in un file
(cont.)
! *** SEZIONE ESECUTIVA *** !
WRITE(*,*) 'Leggo dal file ', nome_file
OPEN (UNIT = 9, FILE = nome_file, STATUS = 'OLD', ACTION = &
&'READ', IOSTAT = istatus)
IF (istatus == 0) THEN
DO
READ (9,100,IOSTAT = istatus) linea
! LETTURA di una linea da file
IF (istatus /= 0) EXIT
WRITE(*,*) linea(1:LEN_TRIM(linea))
linee = linee + 1
caratteri = caratteri + LEN_TRIM(linea)
END DO
WRITE(*,*) 'Il file e'' composto di ', linee, ' linee'
WRITE(*,*) 'e di ', caratteri, ' caratteri'
ELSE
WRITE(*,*) 'Il file ', nome_file, 'non esiste'
END IF
STOP
100 FORMAT(A)
END PROGRAM leggi_file
25
File in Scrittura
! File: util-for.for
MODULE operazioni_su_file
! Questo modulo contiene alcune unita' che effettuano operazioni su
! file.
! - copia_file: copia un file in un altro file
! - stampa_file: stampa un file su schermo
CONTAINS
SUBROUTINE copia_file(sorgente,destinazione)
! *** SEZIONE DICHIARATIVA
IMPLICIT NONE
! ** DICHIARAZIONE ARGOMENTI FITTIZI
CHARACTER(len=*), INTENT(IN) :: sorgente, destinazione
! nomi fisici dei file
! ** DICHIARAZIONE COSTANTI E VARIABILI LOCALI
INTEGER, PARAMETER :: lunghezza_linea = 240
! la lunghezza di linea massima ammessa
CHARACTER(lunghezza_linea) :: linea
! la linea letta di volta in volta
INTEGER :: istatus
26
File in Scrittura (cont.)
WRITE(*,*) 'Sto copiando il file ', sorgente, ' nel file ', destinazione
! apertura del file sorgente in lettura
OPEN (UNIT = 9, FILE = sorgente, STATUS = 'OLD', ACTION = 'READ', &
& IOSTAT = istatus)
IF (istatus == 0) THEN
! apertura del file destinazione in scrittura
OPEN (UNIT=10, FILE=destinazione, STATUS='REPLACE', ACTION='WRITE')
DO
READ (9,100,IOSTAT = istatus) linea
! LETTURA di una linea da file
IF (istatus /= 0) EXIT
WRITE(10,*)linea(1:LEN_TRIM(linea))
END DO
CLOSE(9)
CLOSE(10)
ELSE
WRITE(*,*) 'Il file ', sorgente, 'non esiste'
END IF
27
File in Scrittura (cont.)
WRITE(*,*) 'Copia terminata'
RETURN
100 FORMAT(A)
END SUBROUTINE copia_file
SUBROUTINE stampa_file(nome_file)
! *** SEZIONE DICHIARATIVA *** !
IMPLICIT NONE
! ** DICHIARAZIONE ARGOMENTI FITTIZI
CHARACTER(len=*), INTENT(IN) :: nome_file
! ** DICHIARAZIONE VARIABILI LOCALI
INTEGER, PARAMETER :: lunghezza_linea = 240
CHARACTER(lunghezza_linea) :: linea
! la linea letta di volta in volta
INTEGER :: istatus
28
File in Scrittura (cont.)
! *** SEZIONE ESECUTIVA *** !
OPEN (UNIT = 9, FILE = nome_file, STATUS = 'OLD', ACTION = 'READ',&
& IOSTAT = istatus)
IF (istatus == 0) THEN
WRITE(*,*) 'Contenuto del file ', nome_file
DO
READ (9,100,IOSTAT = istatus) linea
! LETTURA di una linea da file
IF (istatus /= 0) EXIT
WRITE(*,*) linea(1:LEN_TRIM(linea))
END DO
CLOSE(9)
WRITE(*,*) 'Fine file ', nome_file
ELSE
WRITE(*,*) 'Il file ', nome_file, 'non esiste'
END IF
RETURN
100 FORMAT(A)
END SUBROUTINE stampa_file
END MODULE operazioni_su_file
29
File in scrittura (cont.)
! File: copia.for
PROGRAM prova_operazioni_su_file
! Questo programma verifica le unita' del modulo operazioni_su_file
! nel file util-fil.for
! *** SEZIONE DICHIARATIVA *** !
USE operazioni_su_file
IMPLICIT NONE
CHARACTER(12) :: nome_input, nome_output
! *** SEZIONE ESECUTIVA *** !
! acquisizione dei nomi dei file
WRITE(*,*) 'Inserisci il nome del file da cui leggere: '
READ (*,*) nome_input
WRITE(*,*) 'Inserisci il nome del file su cui scrivere: '
READ (*,*) nome_output
! prova delle subroutine
CALL copia_file(nome_input,nome_output)
CALL stampa_file(nome_output)
STOP
END PROGRAM prova_operazioni_su_file
30
Scarica

5. Formato di I/O e Files