2016-06-21 72 views
0

我在fortran中有一段代码。代码将'pq'作为用户的输入,并且是单点。我不想这样做,我想从文件points.txt中读取一组点“pq”,并运行它来获取这些点数,而不是只有一个用户输入。可能吗?代码如下:调用一个子程序而不是一个点的列表

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 

相反读取PQ作为一个单一的点x的,Y从上述代码的用户,我想读取一组从file.txt的点,例如50个点和然后运行子程序Pres和Temperature。 文件的每一行都包含一个点x,y,并且每行中的x和y由几个空格字符分隔。 file.txt的的前几行是:

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 

必须注意的是,长度和浮点数的符号可以改变。 file.txt最初是通过python编写的,格式为x,y为'%-12.8f %-12.8f\n'%。我有以下的代码,试图读取该文件,但我无法从起第3行改为:

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

你可能知道他们在现代编程语言中称为循环和数组。那些是你那种东西的朋友。但同时'module'是fortran 90及以上的关键字,所以你不想命名你自己的modulemodule。 – innoSPG

+1

@innoSPG正式注意。但是我熟悉数组和循环,只是不确定如何为fortran实现它们,我是fortran的新手。谢谢(你的)信息。 – Aspro

回答

0

使用READ语句以星号(*)作为第一个参数要求的用户,而不是输入,使用文件标识符。您需要OPEN包含的点的集合文件,假设它是ASCII:

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

我觉得这个命令的参数是相当自明。 然后假设你的文件包含多行与x和y的值,你可以通过做阅读您的文件的每一行:

READ(10,*) x,y 

如果你有多个点读,只使用一个DO如果你知道的数指向读取,否则为DO WHILE。要采取与50点的例子,这样的事情应该工作:

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 

编辑

你的建议是正确的差不多。您忘记声明pqcharacter(len=2)。因此,你不应该能够通过第1行。 正如我所说,有一个空格分隔符自然地被星号视为一种格式。无论如何,如果您想要完全匹配格式,请使用您编写数据的相同格式。读你的格式的Python,我假设你写了两个彩车用空格分隔,而事实上如果算上你的数字字符的数目:

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

,其给出了Fortran语言的格式如下:

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

X表示Fortran格式的空格分隔符。

然后你就可以在屏幕上写上你的数据具有相同的格式进行检查:

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

它提供:

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 

您可能已经注意到,您的最后一个数字失去精度。这是因为你已经声明了一个简单的实数(4字节)。根据你的编译器real(kind=8)real*8切换您real到8个字节(注意,不要做正确的方式,不便于携带但足以在你的情况)

不要忘记关闭您的文件,你完成交易时与它:

close(12) 
+0

另外,如果您有幸能够访问现代Fortran(2008+)编译器,请使用'newunit'说明符。 – jlokimlin

+0

@Coriolis文件中的点是格式化的,而不是逗号,在这种情况下我该怎么做? – Aspro

+0

@Aspro'read'语句中的第二个星号允许您定义格式。当使用星号时,程序会“按需要”读取数据,实际上这应该足以处理空格分隔符。如果你想确定你的数据是如何读取的,你应该定义一种格式。我建议你阅读关于这个教程的教程,这太复杂了,无法在此处定义。 – Coriolis

相关问题