2013-04-08 5 views
8

Sto provando a leggere un file in memoria in un programma Fortran. Il file ha righe N con due valori in ogni riga. Questo è quello che attualmente faccio (compila e funziona, ma mi dà un output non corretto):Fortran legge il file nell'array - dimensioni trasposte

program readfromfile 
    implicit none 

    integer :: N, i, lines_in_file 
    real*8, allocatable :: cs(:,:) 

    N = lines_in_file('datafile.txt') ! a function I wrote, which works correctly 

    allocate(cs(N,2)) 

    open(15, 'datafile.txt', status='old') 
    read(15,*) cs 

    do i=1,N 
     print *, cs(i,1), cs(i,2) 
    enddo 

end 

quello che speravo di ottenere è stato i dati caricati nella variabile cs, con linee come primo indice e le colonne come secondo, ma quando viene eseguito il codice precedente, per prima cosa stampa una riga con due valori "colonna sinistra", quindi una riga con due valori "colonna destra", quindi una riga con i due successivi "valori colonna sinistra" e così via.

Ecco una descrizione più visivo della situazione:

In my data file:  Desired output:  Actual output: 
A1 B1    A1 B1    A1 A2 
A2 B2    A2 B2    B1 B2 
A3 B3    A3 B3    A3 A4 
A4 B4    A4 B4    B3 B4 

Ho provato commutazione indici nell'assegnazione cs, ma con gli stessi risultati (o segfault, a seconda wether I interruttore anche indici alla stampa dichiarazione). Ho anche provato a leggere i valori riga per riga, ma a causa del formato irregolare del file di dati (delimitato da virgole, non allineato alle colonne) non riuscivo a farlo funzionare affatto.

Come si leggono i dati in memoria il modo migliore per ottenere i risultati desiderati?

risposta

9

Non vedo alcuna virgola nel file di dati. Non dovrebbe fare alcuna differenza con l'input diretto dalla lista. Prova a leggerlo come se lo scrivessi.

do i=1,N 
    read (*,*) cs(i,1), cs(i,2) 
enddo 

Altrimenti se leggi intera matrice in un unico comando, si legge in ordine column-major, cioè cs(1,1), cs(2, 1), ....cs(N,1), cs(1, 2), cs(2,2), ... Questo è l'ordine in cui la matrice viene memorizzato.

+0

Sono sorpreso dal motivo per cui non ho potuto farlo funzionare prima, ma ora lo fa. Grazie! Per quanto riguarda le virgole nel mio file di input, sono presenti nel file effettivo, ma nell'esempio volevo solo visualizzare l'ordinamento degli elementi. –

+0

E un upvote per la spiegazione del perché ha fatto quello che ha fatto quando non funzionava. Altre repliche, signore! =) –

+1

Per i futuri lettori di questo post: volevo generalizzare la lettura a una subroutine che prende solo il nome del file e il numero di righe e colonne da leggere, e si conclude con il seguente costrutto implicito: 'leggi (f, *) ((cs (row, col), col = 1, Ncols), row = 1, Nrows) '. Si noti che le colonne devono essere nel ciclo interno, per le ragioni menzionate da @Vladimir F nella risposta sopra. –