在fortran中如何从fortran中的.dat文件中逐行读取所有字符串

时间:2017-07-09 21:47:48

标签: fortran fortran90 fortran95

我有一个.dat文件,我试图逐行读取并打印它。 有人可以帮忙了解如何在fortran中做到这一点吗?

提前致谢!

数据:

REMARK    GENERATED BY TRJCONV
TITLE     UNNAMED t=   0.00000
REMARK    THIS IS A SIMULATION BOX
CRYST1   26.178   26.178   26.178  90.00  90.00  90.00 P 1           1
MODEL        1
ATOM      1  S2  LJ2     1      17.000  15.030  11.630  1.00  0.00            
ATOM      2  S2  LJ2     2      13.290  11.340  15.900  1.00  0.00            
ATOM      3  S2  LJ2     3      17.030  23.070  14.750  1.00  0.00            
ATOM      4  S2  LJ2     4      15.360  14.840   9.480  1.00  0.00            
ATOM      5  S2  LJ2     5      15.780   4.560   9.580  1.00  0.00            
ATOM      6  S2  LJ2     6       5.350  22.490  11.110  1.00  0.00            
ATOM      7  S2  LJ2     7      19.940   3.910  10.840  1.00  0.00            
ATOM      8  S2  LJ2     8      20.380  13.360  15.680  1.00  0.00            
ATOM      9  S2  LJ2     9      18.340   4.200   7.720  1.00  0.00            
ATOM     10  S2  LJ2    10      18.610  16.530   9.910  1.00  0.00            
TER
ENDMDL

代码:

program atom_test

implicit none

 character (LEN=75) ::inputdatafile,outputfile
 real,dimension(100) :: x, y
 integer :: i,n,nframes
character (len=200),dimension(3000):: command

 print *,"Give the datafile name:"
 read *,inputdatafile
outputfile=inputdatafile(1:len(trim(inputdatafile))-4)//"_output.dat"
!write(*,*)outputfile
Open(9, file=inputdatafile, status='old')

call linesFile(inputdatafile,n)
write(*,*)n

do i=1,n
  read(*,*),command(i)
  write (*,*)command(i)

end do
close(9)

end program atom_test
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! find the number of lines in a file
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine  linesFile(fileIn,n)
implicit none
 Character(len = 50)   :: fileIn
integer, intent(out) :: n
! locals
integer :: iostatus, unit_read
real    :: dummy


unit_read = 9
open(unit=unit_read, file=fileIn)

n =0
DO
  READ(unit_read, *, IOSTAT=iostatus) dummy
  IF (iostatus < 0) EXIT
    n = n + 1
END DO

 ! WRITE(*, '(i8, a, a)') n, ' bins read from file: ', fileIn
 close(unit_read)

end subroutine  linesFile

鉴于明确的答案工作正常。由于我是Fortran的新手,我还有一个问题与此相关。我想从我的数据文件中的ATOM行中单独获取元素 例如: 原子1 S2 LJ2 1 17.000 15.030 11.630 1.00 0.00

from here i want to store 1,s2,LJ2,1,17.000,15.030 each in different parameters. In that case I am using this 

/ *代码标记为正确

    ncount=0
 do i = 1, n

       IF (command(i)(1:4).eq.'ATOM') THEN
         ncount=ncount+1
         read(read_unit,*) p, p2, p3,p4,xatom(ncount)
         write(*,*),p

       endif
end do

但它没有用。你能否给我一个关于如何从以ATOM开头的那些方面单独阅读的建议? 提前谢谢!

2 个答案:

答案 0 :(得分:2)

我立即注意到了一些事情:

  1. read(*, *) command(i)读取标准输入的第一个元素,而不是文件。我想你想要read(9, *)
  2. 实际上,您可能想要read(9, '(A)'),因为您想要读取整行,而不是直到第一个元素分隔符(即空格或逗号)。
  3. 在子程序中,在同一单元下再次打开文件。那是......危险,如果没有错。最好只读取文件,然后使用rewind命令将读取位置移回文件的开头。

    program atom_test
    
        implicit none
        integer :: ios
        integer, parameter :: read_unit = 99
        character(len=200), allocatable :: command(:)
        character(len=200) :: line
        integer :: n, i
    
        open(unit=read_unit, file='data.dat', iostat=ios)
        if ( ios /= 0 ) stop "Error opening file data.dat"
    
        n = 0
    
        do
            read(read_unit, '(A)', iostat=ios) line
            if (ios /= 0) exit
            n = n + 1
        end do
    
        print*, "File contains ", n, "commands"
    
        allocate(command(n))
    
        rewind(read_unit)
    
        do i = 1, n
            read(read_unit, '(A)') command(i)
        end do
    
        close(read_unit)
    
        do i = 1, n
            print*, command(i)
        end do
    
    end program atom_test
    
  4. 如果您在开始时已经投入了3000行,那么没有理由再读两遍:

    program atom_test
    
        implicit none
        integer :: ios
        integer, parameter :: read_unit = 99
        character(len=200) :: command(3000)
        integer :: n, i
    
        open(unit=read_unit, file='data.dat', iostat=ios)
        if ( ios /= 0 ) stop "Error opening file data.dat"
    
        n = 0
    
        do
            read(read_unit, '(A)', iostat=ios) command(n+1)
            if (ios /= 0) exit
            n = n + 1
        end do
    
        print*, "File contains ", n, "commands"
    
        close(read_unit)
    
        do i = 1, n
            print*, command(i)
        end do
    
    end program atom_test
    
  5. 在您的子程序中读取文件中的行数,您尝试从第一个单词通常不是数字的文件中读取REAL。这可能导致IOSTAT非零,即使您尚未到达文件末尾。请务必阅读character变量。

答案 1 :(得分:1)

这篇文章提供了OP评论的答案:

  

我想将元素与数据文件中的ATOM行分开获取

假设input.txt看起来像:

ATOM  1   S2  LJ2  1   17.000  15.030  11.630  1.00  0.00                       
ATOM  2   S2  LJ2  2   13.290  11.340  15.900  1.00  0.00                       
ATOM  3   S2  LJ2  3   17.030  23.070  14.750  1.00  0.00                       
ATOM  4   S2  LJ2  4   15.360  14.840  9.480   1.00  0.00                       
ATOM  5   S2  LJ2  5   15.780  4.560   9.580   1.00  0.00                       
ATOM  6   S2  LJ2  6   5.350   22.490  11.110  1.00  0.00                       
ATOM  7   S2  LJ2  7   19.940  3.910   10.840  1.00  0.00                       
ATOM  8   S2  LJ2  8   20.380  13.360  15.680  1.00  0.00                       
ATOM  9   S2  LJ2  9   18.340  4.200   7.720   1.00  0.00                       
ATOM  10  S2  LJ2  10  18.610  16.530  9.910   1.00  0.00 

你可以

  1. 将列读入字符串
  2. 从字符串中读取实数
  3. 输出结果
  4.       program fort                                                              
          integer n, i                                                              
          parameter (n=10)                                                          
          real r1(n), r2(n), r3(n), r4(n), r5(n), r6(n), r7(n)                      
          character(len=255) format, s1(n), s2(n), s3(n), s4(n), s5(n),             
         &                           s6(n), s7(n), s8(n), s9(n), s10(n)             
          i=1                                                                       
          open(unit=99, file='input.txt')                                           
    2     read(99,3,end=1) s1(i), s2(i), s3(i), s4(i), s5(i),                       
         &                 s6(i), s7(i), s8(i), s9(i), s10(i)                       
          i=i+1                                                                     
          goto 2                                                                    
    3     format(a6,2a4,a5,a4,3a8,a6,a4)                                            
    4     format(a6,f4.1,2x,2a4,f4.1,5f8.3)                                         
    1     close(99)                                                                 
          read(s2,*) r1                                                             
          read(s5,*) r2                                                             
          read(s6,*) r3                                                             
          read(s7,*) r4                                                             
          read(s8,*) r5                                                             
          read(s9,*) r6                                                             
          read(s10,*) r7                                                            
          do i=1,n                                                                  
             write(*,4) s1(i), r1(i), s3(i), s4(i), r2(i),                          
         &              r3(i), r4(i), r5(i), r6(i), r7(i)                           
          enddo                                                                     
          end
    

    输出:

    ATOM   1.0  S2  LJ2  1.0  17.000  15.030  11.630   1.000   0.000
    ATOM   2.0  S2  LJ2  2.0  13.290  11.340  15.900   1.000   0.000
    ATOM   3.0  S2  LJ2  3.0  17.030  23.070  14.750   1.000   0.000
    ATOM   4.0  S2  LJ2  4.0  15.360  14.840   9.480   1.000   0.000
    ATOM   5.0  S2  LJ2  5.0  15.780   4.560   9.580   1.000   0.000
    ATOM   6.0  S2  LJ2  6.0   5.350  22.490  11.110   1.000   0.000
    ATOM   7.0  S2  LJ2  7.0  19.940   3.910  10.840   1.000   0.000
    ATOM   8.0  S2  LJ2  8.0  20.380  13.360  15.680   1.000   0.000
    ATOM   9.0  S2  LJ2  9.0  18.340   4.200   7.720   1.000   0.000
    ATOM  10.0  S2  LJ2 10.0  18.610  16.530   9.910   1.000   0.000
    

    更好的方法是

    1. 将列读入变量(字符串,整数或实数)
    2. 输出结果
    3.       program fort                                                              
            integer n, i                                                              
            parameter (n=10)                                                          
            integer i1(n), i2(n)                                                      
            real r1(n), r2(n), r3(n), r4(n), r5(n)                                    
            character(len=255) format, s1(n), s2(n), s3(n), s4(n), s5(n),             
           &                           s6(n), s7(n), s8(n), s9(n), s10(n)             
            i=1                                                                       
            open(unit=99, file='input.txt')                                           
      2     read(99,3,end=1) s1(i), i1(i), s3(i), s4(i), i2(i),                       
           &                 r1(i), r2(i), r3(i), r4(i), r5(i)                        
            i=i+1                                                                     
            goto 2                                                                    
      3     format(a6,i4,a4,a5,i4,3f8.3,2f6.2)                                        
      4     format(a6,i4,2x,2a4,i4,5f8.3)                                             
      1     close(99)                                                                 
            do i=1,n                                                                  
               write(*,4) s1(i), i1(i), s3(i), s4(i), i2(i),                          
           &              r1(i), r2(i), r3(i), r4(i), r5(i)                           
            enddo                                                                     
            end