Sam*_*Roy 6 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
Run Code Online (Sandbox Code Playgroud)
代码:
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
Run Code Online (Sandbox Code Playgroud)
鉴于标记的答案工作正常。由于我是 Fortran 新手,我还有一个与此相关的问题。我想从我的数据文件中的 ATOM 行中分别获取元素,例如: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
Run Code Online (Sandbox Code Playgroud)
/* 将代码标记为正确
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
Run Code Online (Sandbox Code Playgroud)
但它不起作用。你能给我一个关于如何从以 ATOM 开头的行中单独阅读的建议吗?提前致谢!
我立即注意到了一些事情:
read(*, *) command(i)读取标准输入的第一个元素,而不是从文件中读取。我想你想read(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
Run Code Online (Sandbox Code Playgroud)如果你一开始就已经写了 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
Run Code Online (Sandbox Code Playgroud)在读取文件行数的子例程中,您尝试REAL从第一个单词通常不是数字的文件中读取 a 。这可能会导致IOSTAT非零,即使您还没有到达文件的末尾。始终读取character变量。