2016-06-21 34 views
0

Ich habe ein bestimmtes Stück Code in Fortran. Der Code nimmt 'pq' als eine Eingabe von dem Benutzer und ist ein einzelner Punkt. Anstatt dies zu tun, möchte ich eine Reihe von Punkten 'pq' aus einer Datei points.txt lesen und sie für diese Anzahl von Punkten ausführen, anstatt nur eine einzige Benutzereingabe. Ist es möglich? Der Code lautet wie folgt:Rufen Sie ein Unterprogramm für eine Liste von Punkten anstelle eines einzelnen Punktes

program prop 

     use module 

     implicit none 

     character(len=80) :: ErrorMsg 
     character(2)   :: xy 
     real(8)    :: Conc(20) = 0.d0 
     character(len=20)  :: fn, fl 
     real(8)    :: Mmolar, Tcritical, Pcritical, Tmininimum, Tmaximum, x, y 

call Init_module() 

    write(*,*) 'Insert the gas name:' 
    read(*,*) fn 
    write(*,*) 'Insert the gas library:' 
    read(*,*) fl 


    write(*,*) 'Insert the copule pq:' 
    read(*,*) pq 
    write(*,*) 'Insert the value of ', pq(1:1) 
    read(*,*) x 
    write(*,*) 'Insert the value of ', pq(2:2) 
    read(*,*) y 

write(*,*) 'Pres  = ', Pres(pq, x, y, ErrorMsg) 
    write(*,*) 'Temp = ', Temperature(pq, x, y, ErrorMsg) 

call ReleaseObjects() 

end program prop 

Statt Lesen pq als ein einzelnen Punkt x, y von dem Benutzer in dem obigen Code, ich möchte eine Reihe von Punkten aus datei.txt lesen, zum Beispiel 50 Punkte und Führen Sie dann Subroutinen Pres und Temperature aus. Jede Zeile der Datei enthält einen Punkt x, y und x und y in jeder Zeile sind durch ein paar Leerzeichen voneinander getrennt. Die ersten paar Zeilen datei.txt sind:

Ts 
500 
0.04781564 159.81587875 
0.20396084 165.46398084 
0.08159885 166.81382894 
0.03879184 164.17497877 
0.12585959 165.37000305 
0.09895530 165.95997769 
0.10389518 170.74235496 

Zu beachten ist, dass die Länge und die Zeichen der schwebenden Zahlen variieren kann. Die Datei.txt wird ursprünglich durch Python mit der Formatierung für x geschrieben, wobei y '%-12.8f %-12.8f\n'% ist. Ich habe den folgenden Code zu versuchen, die Datei zu lesen, aber ich bin nicht in der Lage von der 3. Zeile ab zu lesen:

real, allocatable  :: x(:),y(:) 
     integer :: np 

     open(12,file=trim('file.txt'),status='old', & 
      access='sequential', form='formatted', action='read') 

      read(12,*)pq 
      write(*,*)'pq:', pq 

      read(12,*)np 
      write(*,*)'number of points:',np 

      allocate (x(np)) 
      allocate (y(np)) 
      do i=1,np   
      read(12,*)x(i),y(i) 
      write(*,*)x(i),y(i) 
      enddo 
+0

Sie könnten wissen, wie sie Schleifen und Arrays in modernen Programmiersprachen nennen. Das sind deine Freunde für solche Sachen. Aber inzwischen ist 'modul' ein Schlüsselwort in fortran 90 und darüber, also wollen Sie kein eigenes Modulmodul nennen. – innoSPG

+1

@innoSPG Ordentlich vermerkt. Allerdings bin ich vertraut mit Arrays und Schleifen, war nur unsicher, wie man sie für Fortran implementieren, ich bin neu für Fortran. Danke für die Information. – Aspro

Antwort

0

Statt die READ Anweisung mit dem Sternchen der Verwendung (*) als erstes Argument für einen Benutzer zu fragen Geben Sie eine Dateikennung ein. Sie benötigen eine Datei mit dem Satz von Punkten OPEN, es unter der Annahme, ASCII ist:

OPEN(UNIT=10,FILE=file.txt,ACTION='read',STATUS='old') 

Ich denke, die Argumente dieses Befehls ganz erklärend sind. Sie dann Ihre Datei unter der Annahme, mehrere Zeilen mit x enthält und y-Werte, können Sie jede Zeile der Datei, indem Sie lesen:

READ(10,*) x,y 

Wenn Sie mehrere Punkte haben nur zu lesen, ein DO verwenden, wenn Sie die Anzahl der wissen Punkte zu lesen, ein DO WHILE sonst. Um Ihr Beispiel mit 50 Punkten zu nehmen, so etwas wie dies funktionieren soll:

OPEN(UNIT=10,FILE=file.txt,ACTION='read',STATUS='old') ! Open file 
DO i=1,50 
    READ(10,*) x,y 
    write(*,*) 'Pres  = ', Pres(pq, x, y, ErrorMsg) 
    write(*,*) 'Temp = ', Temperature(pq, x, y, ErrorMsg) 
END DO 
CLOSE(10) ! Close file 

EDIT

Ihr Vorschlag fast richtig ist. Sie haben vergessen, pq als character(len=2) zu deklarieren. Sie hätten deshalb nicht in der Lage sein sollen, die erste Zeile zu passieren. Wie gesagt, gibt es ein Leerzeichen Trennzeichen, das natürlich von einem Sternchen als Format behandelt wird. Wenn Sie das Format exakt anpassen möchten, verwenden Sie das gleiche, mit dem Sie Ihre Daten geschrieben haben. Lesen Sie das Format Python, ich nehme an, Sie zwei Schwimmer mit einem Raum Separator schrieb, und in der Tat, wenn Sie die Anzahl der Zeichen Ihrer Ziffern zählen:

0.04781564 159.81587875 
^^^^^^^^^^^^|^^^^^^^^^^^^ 
1   12|1   12 
      | 
      space 

, die das folgende Format in Fortran gibt:

read(12,'(f12.8,1X,f12.8)') x(i),y(i) 

X bedeutet ein Leerzeichen-Trennzeichen in Fortran-Formaten.

Dann können Sie Sie die Daten am Bildschirm mit dem gleichen Format schreiben zu überprüfen:

write(*,'(f12.8,1X,f12.8)') x(i),y(i) 

Es gibt:

pq:Ts 
number of points:   500 
0.04781564 159.81587219 
0.20396084 165.46397400 
0.08159885 166.81382751 
0.03879184 164.17497253 
0.12585959 165.37001038 
0.09895530 165.95997620 
0.10389518 170.74235535 

Sie haben vielleicht bemerkt, dass Sie Präzision auf den letzten Stellen verloren. Es ist, weil Sie eine einfache reale (4 Bytes) deklariert haben. Schalten Sie Ihre real-8 Bytes mit real(kind=8) oder real*8 nach Ihrem Compiler (beachten Sie, nicht der richtige Weg, es zu tun, nicht tragbar, aber ausreichend in Ihrem Fall)

Vergessen Sie nicht, Ihre Datei zu schließen, wenn Sie fertig sind, tun mit ihm:

close(12) 
+0

Verwenden Sie auch den 'newunit'-Spezifizierer, wenn Sie das Glück haben, Zugang zu einem modernen Fortran (2008+) -Compiler zu haben. – jlokimlin

+0

@Coriolis Die Punkte in der Datei sind Leerzeichen anstelle von einem Komma, was mache ich in diesem Fall? – Aspro

+0

@Aspro Das zweite Sternchen in der Anweisung 'read' erlaubt es Ihnen, ein Format zu definieren. Wenn ein Stern verwendet wird, liest das Programm Ihre Daten "wie es will", eigentlich sollte dies ausreichen, um ein Leerzeichen zu behandeln. Wenn Sie sicher sein möchten, wie Ihre Daten gelesen werden, sollten Sie ein Format definieren. Ich empfehle Ihnen, ein Tutorial darüber zu lesen, es ist zu komplex, um es hier zu definieren. – Coriolis