有没有办法压缩这段代码?
.
.
real*4 a4,e4,inc4,capom4,omega4,capm4
integer*2 id2
real*8 array(1e7,8)
.
.
row=0
do n=1,nleft+nbod2-1
row=row+1
read(iu) id2,a4,e4,inc4,capom4,omega4,capm4
array(row,1)=id2
array(row,2)=a4
array(row,3)=e4
array(row,4)=inc4
array(row,5)=capom4
array(row,6)=omega4
array(row,7)=capm4
end do
.
.
我尝试了五种不同的方式,从隐含的DO循环开始,所有结果都是" forrtl:严重(67):输入语句需要太多数据......"。
答案 0 :(得分:2)
你无法凝聚的原因
read(iu) id2,a4,e4,inc4,capom4,omega4,capm4
array(row,1)=id2
array(row,2)=a4
array(row,3)=e4
array(row,4)=inc4
array(row,5)=capom4
array(row,6)=omega4
array(row,7)=capm4
到
read(iu) (array(row,i), i=1:7)
是因为这会导致数据文件与读取参数不匹配。在下面评论中提供的来源中,您将这些变量声明为:
real*4 ttmp,a4,e4,inc4,capom4,omega4,capm4
integer*2 nleft,nbod2,id2
real*8 array(1e7,8)
这意味着您的read
调用read(iu) id2,a4,e4,inc4,capom4,omega4,capm4
正在请求26个字节(1 * 2个字节+ 6 * 4个字节),这对应于注释中提供的无格式文件中的记录大小。
将读取更改为:
read(iu) (array(row,i), i=1:7)
它本身完全有效,它不再匹配二进制文件,读取失败。此读取请求56个字节(7 * 8个字节)并产生您正在报告的致命运行时错误(您从26字节记录请求56个字节)。读取中使用的临时变量是必需的,这样您就可以读取2字节整数和4字节浮点数,然后将它们分配给8字节实数变量。读取无法直接完成此操作,因为文件中的基础二进制数据不是8字节实数。
那你能做什么?
在您下面发布的代码中,您的阅读略有不同
read(iu) id2,a4,e4,inc4,capom4,omega4,capm4
array(row,1)=id2
array(row,2)=ttmp
array(row,3)=a4
array(row,4)=e4
array(row,5)=inc4
array(row,6)=capom4
array(row,7)=omega4
array(row,8)=capm4
你可以取消6个命名的临时变量,而是使用6个实数的数组。 e.g。
real*4 :: readtemp(6)
.
.
do n=1,nleft+nbod2-1
read(iu) id2,readtemp
array(n,1)=id2
array(n,2)=ttmp
array(n,3:8)= readtemp
end do
这可以让您摆脱6个单独的实数换取一个数组,并将6个赋值浓缩为1个赋值。读取/分配组合并不像其他答案那样完全崩溃,但这确实避免了需要定义类型来完成它。
答案 1 :(得分:0)
你还没有真正向我们展示提供非常好的建议。将其留在一边,这可能有用:
替换块
row=0
do n=1,nleft+nbod2-1
row=row+1
read(iu) id2,a4,e4,inc4,capom4,omega4,capm4
array(row,1)=id2
array(row,2)=a4
array(row,3)=e4
array(row,4)=inc4
array(row,5)=capom4
array(row,6)=omega4
array(row,7)=capm4
end do
与
do n=1,nleft+nbod2-1
read(iu) array(n,1:7)
end do
在任何进一步的问题中,请准确发布您遇到问题的代码,以及编译器或运行时报告的错误。
答案 2 :(得分:0)
由于OP的代码涉及包含> y@.Data
[[1]]
[1] 1 2 3 4
[[2]]
[1] 5 6 7 8
的混合数据类型,因此integer*2
的直接使用似乎无效。所以我又做了两次试验来浓缩代码。第一个是
read(iu) array( n, 1:7 )
保存了一些代码行,但仍然有点冗长。所以第二次试验是
read(iu) id2, a4, e4, inc4, capom4, omega4, capm4
array( n, : ) = [ real*8 :: id2, a4, e4, inc4, capom4, omega4, capm4 ]
并将未格式化的文件读为
type dat_t
sequence
integer*2 :: id2
real*4 :: a4, e4, inc4, capom4, omega4, capm4
endtype
type(dat_t) :: dat( 10000 ) !! or allocate() if necessary
获得的数据可以照常使用,例如do n = 1, nleft + nbod2 - 1
read(iu) dat( n )
enddo
。这里放置关键字dat( n )% a4
以确保内存中变量的连续排列非常重要。否则会出现与OP案例相同的错误......
我用下面的代码(使用gfortran4.8和ifort14.0)测试了这个
sequence