在 fortran 中如何从 fortran 中的 .dat 文件逐行读取所有字符串
In fortran how to read all strings line by line from a .dat file in fortran
我有一个 .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
但它不是working.Can请你给我一个建议,关于如何从那些以ATOM开头的行中单独阅读?
提前致谢!
有几件事我立即注意到:
- 行
read(*, *) command(i)
读取标准输入的第一个元素,而不是从文件中读取。我想你想 read(9, *)
.
- 实际上,您可能想要
read(9, '(A)')
因为您想阅读整行,而不仅仅是第一个元素分隔符(即 space 或逗号)。
在您的子例程中,您在同一单元下再次打开文件。那是……即使没有错也是危险的。最好只从文件中读取,然后使用 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
变量。
此 post 提供了对 OP 评论的回答:
I want to get the elements separately from the ATOM rows in my data file
假设 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
我有一个 .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
但它不是working.Can请你给我一个建议,关于如何从那些以ATOM开头的行中单独阅读? 提前致谢!
有几件事我立即注意到:
- 行
read(*, *) command(i)
读取标准输入的第一个元素,而不是从文件中读取。我想你想read(9, *)
. - 实际上,您可能想要
read(9, '(A)')
因为您想阅读整行,而不仅仅是第一个元素分隔符(即 space 或逗号)。 在您的子例程中,您在同一单元下再次打开文件。那是……即使没有错也是危险的。最好只从文件中读取,然后使用
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
变量。
此 post 提供了对 OP 评论的回答:
I want to get the elements separately from the ATOM rows in my data file
假设 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