Fortran新手,关于写入文件的问题

时间:2012-08-01 12:49:36

标签: fortran

我对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指的是我打开(并创建)的文件,并且想要写入。其余的第一个括号做了什么?第二个问题的重点是什么?这会给我提供我想要放入文件的信息吗?万一,DB在哪里填充?

一般来说,我想知道出了什么问题?为什么OUT会改变价值? (我需要

NCOEFF在程序开头定义为Integer,DB:作为DOUBLE PRECISION DB(3000),DB2Z / 0.d0 /,因此我假设DB是某种数组。

4 个答案:

答案 0 :(得分:2)

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

我不熟悉REC参数,但可以找到自己调查的起始位置here

答案 1 :(得分:2)

引用手册REC表示要读取或写入的记录号。如您所知,请参阅编译器随附的文档以获得进一步说明。

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

答案 2 :(得分: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)

答案 3 :(得分:0)

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