0

I'm trying to solve problems related to retaining values, when I use de/allocate in the code shown below (fortran), making a copy array, but the problem persists. I've already seen links related with the topic:

Fortran array automatically growing when adding a value

How to get priorly-unknown array as the output of a function in Fortran

It would be easy and it doesn't make sense (for the purpose of this code) if I know array dimension (input from a txt file).

Possibly I make some mistakes (one of them is obvious: minute dimension against expected total dimension). I will be grateful if someone specify them. Despite of this I can't understand how making a copy array can solve the problem, because I need to de/allocate both the temporary and the main variables.

So, is it possible to read a txt without "variable dimension" info using reallocate (de/allocate)?

That's the code (using 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

(I know better ways to achieve the same goal, that's only an exercise to deepen)

I use this data example (from a txt):

min
 5
10
15
20
25
30
35
40
45
50
55
 0

That's the result:

-2144186072 1 -2144186072 1 25 0 35 40 45 50

user
  • 309
  • 1
  • 9

1 Answers1

1

In the reallocation process you deallocate minuto and don't save its old data.

This is a sample program which could work out for you

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

Output

$  gfortran -g3 -Wall -fcheck=all a.f90 && ./a.out
           5          10          15          20          25          30          35          40          45          50          55           0
jack
  • 1,658
  • 1
  • 7
  • 18
  • I would point out that `move_alloc()` is Fortran 2003 and not Fortran 90. It does not really matter these days, but @Isaac appearsedto be asking for Fortran 90 in particular. Otherwise all the links he got before (also in the previous question) apply as well. – Vladimir F Героям слава Dec 25 '20 at 16:28