1

我对 Fortran 完全陌生,对编程也很陌生。我正在尝试编译其他人编写的脚本。这给我带来了一些问题。代码的上半部分是:

C 
C Open direct-access output file ('JPLEPH')
C 
OPEN ( UNIT = 12, 
. FILE = 'JPLEPH', 
. ACCESS = 'DIRECT', 
. FORM = 'UNFORMATTED', 
. RECL = IRECSZ, 
. STATUS = 'NEW' )


C
C Read and write the ephemeris data records (GROUP 1070). 
C 
CALL NXTGRP ( HEADER ) 

IF ( HEADER .NE. 'GROUP 1070' ) CALL ERRPRT(1070,'NOT HEADER') 

NROUT = 0 
IN = 0 
OUT = 0 


1 READ(*,'(2i6)')NRW,NCOEFF
if(NRW .EQ. 0) GO TO 1
READ (*,'(3D26.18)',IOSTAT =IN) (DB(K),K=1,NCOEFF) 


DO WHILE ( ( IN .EQ. 0 ) 
. .AND. ( DB(2) .LT. T2) ) 

IF ( 2*NCOEFF .NE. KSIZE ) THEN 
CALL ERRPRT(NCOEFF,' 2*NCOEFF not equal to KSIZE') 
ENDIF 

C
C Skip this data block if the end of the interval is less 
C than the specified start time or if the it does not begin 
C where the previous block ended. 
C 
IF ( (DB(2) .GE. T1) .AND. (DB(1) .GE. DB2Z) ) THEN 

IF ( FIRST ) THEN 
C 
C Don't worry about the intervals overlapping 
C or abutting if this is the first applicable 
C interval. 
C 
DB2Z = DB(1) 
FIRST = .FALSE. 
ENDIF 

IF (DB(1) .NE. DB2Z ) THEN 
C 
C Beginning of current interval is past the end 
C of the previous one.

CALL ERRPRT (NRW, 'Records do not overlap or abut') 
ENDIF 

DB2Z = DB(2) 
NROUT = NROUT + 1

print*,'Out =', OUT

WRITE (12,REC=NROUT+2,IOSTAT=OUT) (DB(K),K=1,NCOEFF)

print*,'Out2 =', OUT


IF ( OUT .NE. 0 ) THEN 
CALL ERRPRT (NROUT, 
. 'th record not written because of error') 
ENDIF 

因此,当我在屏幕上打印“Out”和“Out2”时,我发现 Out=0 和 Out2=110。因为它不再等于零,所以程序给了我一个错误。因此,我基本上想知道这里发生了什么:

WRITE (12,REC=NROUT+2,IOSTAT=OUT) (DB(K),K=1,NCOEFF)

我假设 12 指的是我已经打开(并创建)并想要写入的文件。第一个括号的其余部分是做什么的?第二个有什么意义?这是否给了我想要放入文件的信息?以防万一,数据库在哪里填充?

通常我想知道出了什么问题?为什么 OUT 会改变值?(我需要

NCOEFF 在程序开始时被定义为整数,而 DB: 作为 DOUBLE PRECISION DB(3000), DB2Z/0.d0/ ,所以我假设 DB 是某种数组。

4

4 回答 4

2

在这个程序中,OUT判断write语句是否成功。(语句的IOSTAT参数write表示“I/O 状态”或输入/输出状态)。如果 I/O 操作成功,则返回 0,否则返回错误代码的编号。您可以在此处找到错误代码的含义。

我不熟悉该REC参数,但可以在此处找到调查自己的起点。

于 2012-08-01T13:02:31.367 回答
2

引用手册REC表明要读取或写入的记录号。按照建议,请参阅编译器随附的文档以获取进一步说明。

(DB(K),K=1,NCOEFF)DB表示 '从 1 到的所有元素NCOEFF。您正在查看一份io-implied-do声明。

于 2012-08-01T13:57:02.810 回答
1

该声明

WRITE (12,REC=NROUT+2,IOSTAT=OUT) (DB(K),K=1,NCOEFF)

就是,如果我没记错的话,称为“隐含的 DO 循环”。如所写,它将从数组 DB 中写入 NCOEFF 值,从 DB(1) 开始。

它被称为隐含 DO 循环,因为显式形式(在 FORTRAN IV 中,对于古人来说:我比更现代的变体更了解它)类似于以下内容:

      DO 10 K=1,NCOEFF
      WRITE (12,REC=NROUT+2,IOSTAT=OUT) DB(K)
10    CONTINUE

(假设前两行缩进了六列。)这是一个 DO 循环。隐含的 DO 循环形式允许您将“循环”正确地放在输入/输出语句中。

它的有用之处在于您可以拥有多个数组和多个循环。举个简单的例子:

WRITE (12,REC=NROUT+2,IOSTAT=OUT) (DB(K), DC(K), K=1,NCOEFF)
于 2012-08-01T13:55:38.767 回答
0

110 是 WRITE 调用抛出的错误代码。您需要检查您的 FORTRAN RTL(运行时库)参考。它应该列出可能的错误代码。我认为 110 意味着您正在尝试将双精度值转换为整数,但该值大于您可以存储在整数中的值。也许将值转储DB并查看。

于 2012-08-01T14:54:20.640 回答