(1) 处的可分配数组 '' 必须具有延迟形状或假定等级,以及 (1) 处 READ 语句中的语法错误错误
Allocatable array '' at (1) must have a deferred shape or assumed rank, and Syntax error in READ statement at (1) errors
我正在尝试读取 ASCII 文件,但在编译时遇到错误,例如:
Error: Syntax error in READ statement at (1)
和
Error: Allocatable array 'pos' at (1) must have a deferred shape or assumed rank
我的代码:
subroutine read_file(pos,mass,rho,vel,n)
integer :: i, n
real, allocatable, intent(out) :: pos(3,n), mass(n), rho(n), vel(3,n)
open(unit=11,file="star.ascii",status="old",action="read")
n = 0
do
read(unit=11,*)
n = n+1
enddo
allocate(pos(3,n), mass(n), rho(n), vel(3,n))
do i = 1,n
read(unit=11,*) pos(:,i), mass(i), rho(i), vel(:,i)
enddo
close(unit=11)
end subroutine read_file
我的 ascii 文件中的前 8 列是位置、质量、密度的 x、y、z 分量,以及我读入数组的速度的 x、y、z 分量,其中 (1,n ), (2,n), (3,n) 分别是x,y,z分量,n应该是粒子数。
我哪里做错了,我该如何编译这段代码?
更新:第一个错误已解决,但 READ 语句仍然出现相同的语法错误。
subroutine read_file(pos,mass,rho,vel,n)
integer :: i, n, ios
real, allocatable, intent(out) :: pos(:,:),mass(:),rho(:),vel(:,:)
open(unit=11,file="star.ascii",status="old",action="read")
n = 0
do
read(unit=11,*,iostat=ios) pos,mass,rho,vel
if (ios /= 0) exit
n = n+1
enddo
allocate(pos(3,n), mass(n), rho(n), vel(3,n))
rewind(11)
do i = 1,n
read(unit=11,*)pos(:,i),mass(i),rho(i),vel(:,i)
enddo
close(unit=11)
end subroutine read_file
read
语法错误是因为您使用了命名伪参数 (unit=11
) 但随后您没有继续使用命名伪参数。
假设您有一个带有此接口的子例程:
subroutine mysub(a, b, c)
implicit none
integer, intent(in), optional :: a, b, c
end subroutine mysub
调用这样的子程序有两种方式:
没有命名的虚拟参数:
call mysub(1, 2, 3) ! a->1, b->2, c->3
call mysub(4711, 2) ! a->4711, b->2, c unset
使用所谓的关键字参数:
call mysub(a=4, c=2) ! b unset
call mysub(b=14) ! a and c unset
在情况 1 中,编译器根据参数在接口中定义的顺序解释输入。在情况 2 中,它通过关键字参数设置它们。在某种程度上,你可以混合一点:
call mysub(1, c=5) ! b unset
但是,这很重要,在第一个关键字参数之后,您不能返回:
call mysub(b=4, 2) ! DOES NOT WORK
在这种情况下,编译器不知道 a 还是 c 应该是 2。您可能会说,"What if I use mysub(a=1, 2, 3)
, that's clear, isn't it?" 可能是,但为了避免陷阱,Fortran 指南声明
... once a keyword argument appears in the list, all of the remaining arguments must also be keyword arguments1
read
的接口第一个参数是 unit
,第二个参数是 fmt
。所以你可以选择其中之一:
read(unit=11, fmt=*, iostat=ios) ...
read(11, *, iostat=ios) ...
但是你不能在不声明 fmt=
的情况下使用 unit=
如果你声明一个可分配数组,你需要告诉它你想要分配的维数。这不是用 n
完成的,而是用冒号 :
:
real, allocatable :: pos(:, :), mass(:), rho(:), vel(:, :)
1 来自 Chapman:Fortran 95/2003 供科学家和工程师使用
我正在尝试读取 ASCII 文件,但在编译时遇到错误,例如:
Error: Syntax error in READ statement at (1)
和
Error: Allocatable array 'pos' at (1) must have a deferred shape or assumed rank
我的代码:
subroutine read_file(pos,mass,rho,vel,n)
integer :: i, n
real, allocatable, intent(out) :: pos(3,n), mass(n), rho(n), vel(3,n)
open(unit=11,file="star.ascii",status="old",action="read")
n = 0
do
read(unit=11,*)
n = n+1
enddo
allocate(pos(3,n), mass(n), rho(n), vel(3,n))
do i = 1,n
read(unit=11,*) pos(:,i), mass(i), rho(i), vel(:,i)
enddo
close(unit=11)
end subroutine read_file
我的 ascii 文件中的前 8 列是位置、质量、密度的 x、y、z 分量,以及我读入数组的速度的 x、y、z 分量,其中 (1,n ), (2,n), (3,n) 分别是x,y,z分量,n应该是粒子数。
我哪里做错了,我该如何编译这段代码?
更新:第一个错误已解决,但 READ 语句仍然出现相同的语法错误。
subroutine read_file(pos,mass,rho,vel,n)
integer :: i, n, ios
real, allocatable, intent(out) :: pos(:,:),mass(:),rho(:),vel(:,:)
open(unit=11,file="star.ascii",status="old",action="read")
n = 0
do
read(unit=11,*,iostat=ios) pos,mass,rho,vel
if (ios /= 0) exit
n = n+1
enddo
allocate(pos(3,n), mass(n), rho(n), vel(3,n))
rewind(11)
do i = 1,n
read(unit=11,*)pos(:,i),mass(i),rho(i),vel(:,i)
enddo
close(unit=11)
end subroutine read_file
read
语法错误是因为您使用了命名伪参数 (unit=11
) 但随后您没有继续使用命名伪参数。
假设您有一个带有此接口的子例程:
subroutine mysub(a, b, c)
implicit none
integer, intent(in), optional :: a, b, c
end subroutine mysub
调用这样的子程序有两种方式:
没有命名的虚拟参数:
call mysub(1, 2, 3) ! a->1, b->2, c->3 call mysub(4711, 2) ! a->4711, b->2, c unset
使用所谓的关键字参数:
call mysub(a=4, c=2) ! b unset call mysub(b=14) ! a and c unset
在情况 1 中,编译器根据参数在接口中定义的顺序解释输入。在情况 2 中,它通过关键字参数设置它们。在某种程度上,你可以混合一点:
call mysub(1, c=5) ! b unset
但是,这很重要,在第一个关键字参数之后,您不能返回:
call mysub(b=4, 2) ! DOES NOT WORK
在这种情况下,编译器不知道 a 还是 c 应该是 2。您可能会说,"What if I use mysub(a=1, 2, 3)
, that's clear, isn't it?" 可能是,但为了避免陷阱,Fortran 指南声明
... once a keyword argument appears in the list, all of the remaining arguments must also be keyword arguments1
read
的接口第一个参数是 unit
,第二个参数是 fmt
。所以你可以选择其中之一:
read(unit=11, fmt=*, iostat=ios) ...
read(11, *, iostat=ios) ...
但是你不能在不声明 fmt=
unit=
如果你声明一个可分配数组,你需要告诉它你想要分配的维数。这不是用 n
完成的,而是用冒号 :
:
real, allocatable :: pos(:, :), mass(:), rho(:), vel(:, :)
1 来自 Chapman:Fortran 95/2003 供科学家和工程师使用