【问题标题】:New to Fortran, questions about writing to fileFortran 新手,关于写入文件的问题
【发布时间】:2012-08-01 12:49:36
【问题描述】:

我对 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 在程序开始时定义为 Integer,而 DB: 定义为 DOUBLE PRECISION DB(3000), DB2Z/0.d0/ ,所以我假设 DB 是某种数组。

【问题讨论】:

  • 为了能够有效地使用该语言,请获取您正在使用的编译器的用户指南或程序员指南。

标签: fortran


【解决方案1】:

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

我不熟悉REC 参数,但可以在here 找到一个调查自己的起点。

【讨论】:

  • 谢谢!这让事情变得更清楚了一些。但是其他括号有什么作用? (DB(K),K=1,NCOEFF) ?关于为什么手术不成功的任何想法?
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    声明

    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)
    

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-01
        • 2011-02-17
        • 1970-01-01
        • 1970-01-01
        • 2020-04-30
        • 2023-03-25
        • 2012-09-30
        • 2011-11-11
        相关资源
        最近更新 更多