2012-03-26 9 views
11

Mi piacerebbe avere un'istruzione di scrittura Fortran formattata in base ad alcune variabili. Per esempio, ho potuto scrivere:Stringa di formato per l'output dipendente da una variabile

write(*,'(3f15.3,3f9.2)') x,y,z,(var(i),i=1,nvari) 

dove nvari = 3. Ma, cosa succede se, in alcuni casi, ho effettivamente 4 variabili (ad esempio nvari = 4). Vorrei scrivere qualcosa del genere:

write(*,'(3f15.3,nvari(f9.2))') x,y,z,(var(i),i=1,nvari) 

Ora, nvari posso essere qualsiasi cosa e l'uscita funzionerà come mi piace. Come posso fare qualcosa come questo lavoro?

+1

sono '3' e' 4' le uniche scelte? O stai cercando qualcosa in grado di gestire qualsiasi numero? – sarnold

+1

OP specificato 'nvari può essere qualsiasi cosa'. – patrickvacek

risposta

14

Se si utilizza Intel Fortran, ha un'estensione proprietaria per questo - è possibile includere una variabile esistente tra parentesi angolari di agire come un identificatore:

write(*,'(3f15.3,<nvari>f9.2)') x,y,z,(var(i),i=1,nvari) 
+0

Oh, bello. Grazie per questa risposta. Questo è esattamente quello che volevo. –

+0

c'è un modo per fare alcune operazioni matematiche su ''? ad esempio - ' + 2' o' 3 * 'o' ** 2' nella dichiarazione di formato? ho provato con una parentesi .. che non ha funzionato! EDIT: la soluzione che uso ora è definire un'altra variabile intera 'nfmt' e usarla al posto di' nvari' –

+0

C'è un modo per usare 'A ' formattazione di stile usando il compilatore gfortran? – Chris

10

Se compilatore supporta, '(3f15.3, *(f9.2))'

Se si dispone di un compilatore vecchio, basta usare un numero maggiore di quello che avrà elementi in uscita, ad esempio, '(3f15.3, 999(f9.2))'. Non è necessario utilizzare il formato.

Per i casi più complicati è possibile scrivere un formato ad una stringa e l'uso che come formato:

write (string, '("(3f15.3, ", I4, "(f9.2))")') nvari 
write (*, string) x,y,z, (array(i), i=1,nvari) 

Con la comprensione di formati, incluso il formato reversione, l'uso di formati di stringa è raramente necessaria.

+0

Freddo. Grazie.Sto usando Intel Fortran Compiler, che presumo sia piuttosto recente. Ma comunque, non fa il '(3f15.3, * (f9.2))', quindi sto usando la seconda soluzione. A proposito, cosa intendi per "format reversion"? Ho fatto un po 'di googling, ma non mi è venuto in mente molto. –

8

Invece di scrivere il formato direttamente nell'istruzione di scrittura, è anche possibile utilizzare una variabile di carattere.

character(len=32) :: my_fmt 
my_fmt = '(3f15.3,3f9.2)' 
write(*, my_fmt) x, y, z, (var(i), i = 1, nvari) 

Ora è possibile manipolare la variabile carattere per contenere il numero di ripetizioni desiderato prima dell'istruzione di scrittura, utilizzando una cosiddetta scrittura interna, o scrivere file interno.

write(my_fmt, '(a, i0, a)') '(3f15.3,', nvari, 'f9.2)' 

(. Solo assicurarsi che la lunghezza dichiarata di my_fmt è abbastanza a lungo per contenere l'intera stringa di caratteri)

+1

Oppure, con l'ultima istruzione (parentetica), usa una variabile di carattere allocatable-lenght. –

+0

@HighPerformanceMark: Certo, se il compilatore lo supporta, sarebbe la soluzione migliore. – eriktous

+1

Per coloro che utilizzano il compilatore gfortran, questa soluzione è la soluzione consigliata nella documentazione di gfortran. Vedi "Variabili FORMAT espressioni" nella documentazione (sezione 6.2.3 per gfortran 4, gfortran 5; sezione 6.2.2 per gfortran 6). –

4

volevi scrivere qualcosa del genere:

write(*,'(3f15.3,nvari(f9.2))') x, y, z, (var(i), i=1,nvari) 

In realtà, v'è un vecchio trucco nello standard Fortran che consente di omettere l'nvari, in tal modo:

write(*,'(3f15.3,(f9.2))') x, y, z, (var(i), i=1,nvari) 

o anche così:

write(*,'(3f15.3,f9.2)') x, y, z, (var(i), i=1,nvari) 

La norma dice che l'ultimo descrittore nel formato è ripetuto implicitamente tutte le volte che è necessario per accogliere tutte le variabili nella lista. E 'ultima descrittore' potrebbe essere racchiusa tra parentesi in modo tale che l'ultimo gruppo di descrittori è implicitamente ripetuto, ad esempio:

write(*,'(3f15.3,(2x,f9.2))') x, y, z, (var(i), i=1,nvari) 
Problemi correlati