I have translated the suggestion by @VladimirF (in the comment) as in the following. Though the definition of vector_t is rather lengthy (which may be somewhat similar to vector in extending the size automatically), the caller program becomes a bit shorter.
module vector_mod
implicit none
type vector_t
integer, allocatable :: elem(:) !! elements
integer :: n !! current vector size (<= size(elem))
contains
procedure :: push
procedure :: resize
procedure :: fit
end type
contains
subroutine push ( v, x )
class(vector_t) :: v
integer :: x
if ( allocated( v% elem ) ) then
if ( v% n == size( v% elem ) ) call v% resize( v% n * 2 )
v% n = v% n + 1
v% elem( v% n ) = x
else
allocate( v% elem( 1 ) )
v% n = 1
v% elem( 1 ) = x
endif
end subroutine
subroutine resize ( v, n )
class(vector_t) :: v
integer :: n
integer, allocatable :: buf(:)
integer :: m
allocate( buf( n ), source=0 )
m = min( n, size(v% elem) )
buf( 1:m ) = v% elem( 1:m )
deallocate( v% elem )
call move_alloc ( buf, v% elem )
end subroutine
subroutine fit ( v )
class(vector_t) :: v
call v% resize( v% n )
end subroutine
end
program main
use vector_mod, only: vector_t
implicit none
type(vector_t) :: v
integer x, ios
open( 10, file="test.dat", status="old" )
do
read( 10, *, iostat=ios ) x
if ( ios /= 0 ) exit
call v% push( x )
enddo
close( 10 )
call v% fit()
print *, v% elem(:)
end
But IMHO I guess the solution given in the Question (i.e., open the file, read everything from it, find n, then allocate A(n) and then reread the file) will be the simplest after all...