我有一个 .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 开头的行中单独读取的建议吗? 提前致谢!
最佳答案
我立即注意到一些事情:
- 行
read(*, *) command(i)
读取标准输入的第一个元素,而不是从文件中读取。我想你想阅读(9, *)
。 - 实际上,您可能需要
read(9, '(A)')
因为您想读取整行,而不仅仅是直到第一个元素分隔符(即空格或逗号) . 在子例程中,您在同一单元下再次打开文件。那是……即使没有错,也是危险的。最好只从文件中读取,然后使用
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
如果您已经在开始时指定了 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
在读取文件行数的子例程中,您尝试从第一个单词通常不是数字的文件中读取
REAL
。这可能会导致 IOSTAT 不为零,即使您尚未到达文件末尾。始终读取字符
变量。
关于fortran - 在 fortran 中如何从 fortran 中的 .dat 文件中逐行读取所有字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45001335/