我的问题是如何从文本文件的末尾开始读取。 例如,
do
read(1,*) i
print *,i
end do
将读取文件1中的每一行,并将内容打印到终端。我将如何从文件末尾开始?
答案 0 :(得分:4)
可以通过在read语句中使用inquire
,access=stream
和pos
标签来实现所需的功能。快速进行10分钟的锻炼即可得出以下结论。
program foo
implicit none
integer fd, i, j, m, n
character, allocatable :: s(:)
character :: c
open(newunit=fd,file='foo.f90',access='stream',status='old', &
position='append')
inquire(fd, pos=n)
allocate(s(n))
m = 1
do i = n-1, 1, -1
read(fd, pos=i) c
s(m:m) = c
if (iachar(c) == 10) then
do j = m, 1, -1
write(*,'(A1)',advance='no') s(j)
end do
m = 1
else
m = m + 1
end if
end do
write(*,*)
do j = m-1, 1, -1
write(*,'(A1)',advance='no') s(j)
end do
write(*,*)
close(fd)
end program foo
将其保存到名为foo.f90的文件中,然后编译并运行。这里的人可以使其更优雅。已修改的原始版本:s(j)
不需要使用数组节。
答案 1 :(得分:2)
不可能。阅读总是从某个点开始,然后向前进行。默认情况下,它从第一个字节开始;但您可以跳到其他位置。
关键问题是,在自由格式文件中,除非您阅读文件,否则无法知道行的开头。您可以跳到最后一个字节,检查它是否是行分隔符,然后跳到最后一个字节(如果不是),然后爬回直到找到换行符,但这效率很低。
一种更好的方法是一次读取整个文件,记住换行符在哪里;然后向后迭代此数组,跳转到每一行的开始位置以读取它。这虽然效率不高,但也不是很好。
如果有足够的内存,最好的方法是将整个文件读入一个行数组,然后反转该数组在内存中。