0

I want to insert an unknown number of values in an array (no matter the order). I could first read how many values are to be inserted, then allocate the allocatable array, and finally read its values, as in the following code

PROGRAM try
IMPLICIT NONE
INTEGER :: N
REAL, DIMENSION(:), ALLOCATABLE :: x
WRITE (*,*) "how many values?"
READ (*,*) N
ALLOCATE(x(N))
WRITE (*,*) "insert the values"
READ (*,*) x
END PROGRAM

What if I want to insert the values without declaring how many before allocating the array? I think I should use a DO WHILE cycle to insert the values in ascending order, till a descending value is insert, thus indicating the sequence is ended. I think a part of the code would be the following,

index = 1
WRITE(*,*) x
READ(*,*) x(index)
exit = .FALSE.
DO WHILE (exit.EQV..FALSE.)
    index = index + 1
    READ(*,*) x(index)
    IF (x(index)>x(index-1)) THEN
        exit = .TRUE.
        index = index - 1
    END IF
END DO

How to declare the array x?

Enlico
  • 23,259
  • 6
  • 48
  • 102
  • 1
    Always use tag [tag:fortran]. Add version tags only when it is necessary to specify a specific version and, for example, more recent version is not acceptable. For example, the Mark's answer uses Fortran 2003. Did you really intend to avoid that and only use Fortran 95? – Vladimir F Героям слава Jan 28 '16 at 22:26
  • 1
    I deleted my answer to this question. It was, at best, misdirection. After OP pointed out that the question referred to entering data from the keyboard (clear as the nose on my face but I missed it, d'ohhh) I revised my answer from *here's how to do that* to *don't do that*. OP's first approach is far better than OP's second. If you're interested in any more from me on the topic see http://stackoverflow.com/questions/35077833/fortran-how-do-i-allocate-arrays-when-reading-a-file-of-unknown-size – High Performance Mark Jan 29 '16 at 10:58

1 Answers1

0

I tried with the following solution, building on the concept "a lot of memory allocation and reallocation" expressed by @High Performance Mark.

PROGRAM COEFFS

USE COMPACT

IMPLICIT NONE

REAL, DIMENSION(:), ALLOCATABLE :: x,x2
INTEGER :: nL,nR,nT,index,oL,oR
LOGICAL :: exit

WRITE(*,*) "Input an increasing sequence of reals (end the sequence &
        & with the first decreasing element, which will be discarded):"

index = 1
ALLOCATE(x(index))
READ(*,*) x(index)
ALLOCATE(x2(index))
x2 = x
DEALLOCATE(x)
exit = .FALSE.
DO WHILE (exit.EQV..FALSE.)
    index = index + 1
    ALLOCATE(x(index))
    x(1:index-1) = x2
    READ(*,*) x(index)
    DEALLOCATE(x2)
    ALLOCATE(x2(index))
    x2 = x
    DEALLOCATE(x)
    IF (x2(index)<x2(index-1)) THEN
        exit = .TRUE.
        index = index - 1
        ALLOCATE(x(index))
        x = x2(1:index)
    END IF
END DO
DEALLOCATE(x2)

WRITE(*,*) "x = ", x

END PROGRAM

With the array being input by keyboard, I don't think allocation/reallocation is a problem, since it happens at a much higher speed than that of my fingers typing the values, doesn't it? Still I think the code could be made better. For instance, using two arrays is the only way to take advantage of allocation/reallocation?

Enlico
  • 23,259
  • 6
  • 48
  • 102
  • 1
    Yes, I see that now (d'ohhhh). It's not the question that's wrong, it's the approach. As you've seen, fiddling around trying to allocate an array to an (initially) unknown size is, at best, fiddly. Don't do it. Tell the program how many values you are going to enter, enter them. – High Performance Mark Jan 29 '16 at 08:26
  • Oh, I got the point, be sure (this is the what happens when one passes from MATLAB, to a real programming language, ahahah). Apart from this, is my approach the best way (among the worst ones) to do this horrible thing (i.e. to input from keyboard an array of unknown size without specifying the size itself)? – Enlico Jan 29 '16 at 15:41
  • I don't like it. If you must do this use modern Fortran's automatic re-allocation on assignment. As I showed in the first part of my now-and-forever deleted answer. – High Performance Mark Jan 29 '16 at 17:11