我有一个.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开头的那些方面单独阅读的建议? 提前谢谢!
答案 0 :(得分:2)
我立即注意到了一些事情:
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
如果您在开始时已经投入了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
非零,即使您尚未到达文件末尾。请务必阅读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
你可以
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
更好的方法是
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