问题描述
我正在尝试解决与保留值相关的问题,当我在下面显示的代码 (fortran) 中使用 de/allocate 时,制作了一个副本数组,但问题仍然存在。我已经看到与该主题相关的链接:
Fortran array automatically growing when adding a value
How to get priorly-unknown array as the output of a function in Fortran
如果我知道数组维度(从 txt 文件输入),这将很容易并且没有任何意义(对于此代码而言)。
可能我犯了一些错误(其中一个很明显:分钟维度与预期总维度)。如果有人指定它们,我将不胜感激。尽管如此,我还是无法理解制作复制数组如何解决问题,因为我需要解除/分配临时变量和主变量。
那么,是否可以使用重新分配(取消/分配)读取没有“可变维度”信息的 txt?
这是代码(使用 f90):
program prueba
implicit none
integer,dimension(:),allocatable :: minuto,temp
integer :: IoUnit,ierr
integer :: i = 1
integer :: n = 1
open(newunit = IoUnit,file = 'datos.txt')
read(IoUnit,*)
allocate(minuto(n),temp(n))
minuto = 0; temp = 0
!-------------------------------------------
do
read(unit = IoUnit,fmt = '(i2)',iostat = ierr) temp(i)
if (ierr/=0) exit
if (mod(size(temp,1),5)==0) then
deallocate(minuto)
allocate(minuto(i))
minuto((i-4):i) = temp((i-4):i)
end if
i = i+1
deallocate(temp)
allocate(temp(i))
end do
close(IoUnit)
print*,minuto
end program prueba
(我知道实现相同目标的更好方法,这只是加深练习)
我使用这个数据示例(来自 txt):
min
5
10
15
20
25
30
35
40
45
50
55
0
结果如下:
-2144186072 1 -2144186072 1 25 0 35 40 45 50
解决方法
在重新分配过程中,您会取消分配 minuto 并且不保存其旧数据。
这是一个可以为您工作的示例程序
program prueba
implicit none
integer,allocatable :: minuto(:)
integer,parameter :: n = 2
integer :: iounit,ierr,temp(n),i
open (newunit = iounit,file = 'datos.txt')
read (iounit,*)
! init minuto. needed for move_alloc in first call
allocate (minuto(0))
i = 1
do
read (unit = iounit,fmt = '(i2)',iostat = ierr) temp(i)
! exit loop. still save temp(1:i-1)
if (ierr /= 0) then
if (i > 1) call save_temp(i-1)
exit
end if
! save all of temp
if (i == n) call save_temp(n)
i = mod(i,n) +1
end do
close (iounit)
print *,minuto
contains
subroutine save_temp(n_temp)
!! append temp(1:n_temp) to minuto
integer,intent(in) :: n_temp
integer,allocatable :: temp_reloc(:)
! save old data from minuto into temp_reloc
call move_alloc(minuto,temp_reloc)
allocate (minuto(size(temp_reloc) + n_temp))
! init first part of minuto by its old data
minuto(:size(temp_reloc)) = temp_reloc
! append temp's data
minuto(size(temp_reloc)+1:) = temp(1:n_temp)
end subroutine
end program
输出
$ gfortran -g3 -Wall -fcheck=all a.f90 && ./a.out
5 10 15 20 25 30 35 40 45 50 55 0