如何将数据读入数组

时间:2016-12-28 18:55:48

标签: fortran fortran77

我有一个工程教科书中的FORTRAN 77代码,我想利用它。问题是我无法理解如何将数据输入到被称为FDAM1(61),FDAM2(61),FPOW1(61),FPOW2(61),UDAM(61)UPOW(61).

的数组中

供您参考,代码摘自本书第49页:https://books.google.pt/books?id=i2hyniQpecYC&lpg=PR6&dq=optimal%20design%20siddall&pg=PA49#v=onepage&q=optimal%20design%20siddall&f=false

C     PROGRAM TST (INPUT,OUTPUT,TAPE5=INPUT,TAPE6=OUTPUT)
C
C     PROGRAM TO ESTIMATE MAXIMUM EXPECTED VALUE FOR ALTERNATE DESIGNS
C
C     FDENS(I)= ARRAYS FOR DATA DEFINING DENSITY FUNCTIONS
C     FDAM1(I)= ARRAY DEFINING DENSITY FUNCTION FOR DAMAGE IN DESIGN 1
C     DFAM2(I)= ARRAY DEFINING DENSITY FUNCTION FOR DAMAGE IN DESIGN 2
C     FPOW1(I)= ARRAY DEFINING DENSITY FUNCTION FOR POWER IN DESIGN 1
C     FPOW2(I)= ARRAY DEFINING DENSITY FUNCTION FOR POWER IN DESIGN 2
C     UDAM(I)= VALUE CURVE FOR DAMAGE
C     UPOW(I)= VALUE CURVE FOR POWER
C
      DIMENSION FDENS(61),FDAM1(61),FDAM2(61),FPOW1(61),FPOW2(61),
     1UDAM(61),UPOW(61),FUNC(61)
C
C     NORMALIZE DENSITY FUNCTIONS
C
      DO 1 I=1,4
      READ(5,10)(FDENS(J),J=1,61)
      READ(5,11)RANGE
      AREA=FSIMP(FDENS,RANGE,61)
      DO 2 J=1,61
      GO TO(3,4,5,6)I
3     FDAM1(J)=FDENS(J)/AREA
      GO TO 2
4     FDAM2(J)=FDENS(J)/AREA
      GO TO 2
5     FPOW1(J)=FDENS(J)/AREA
      GO TO 2
6     FPOW2(J)=FDENS(J)/AREA
2     CONTINUE
1     CONTINUE
C
C     DETERMINE EXPECTED VALUES
C
      READ(5,10)(UDAM(J),J=1,61)
      READ(5,10)(UPOW(J),J=1,61)
      DO 20 I=1,6
      GO TO (30,31,32,33,34,35)I
30    DO 40 J=1,61
40    FUNC(J)=FDAM1(J)*UDAM(J)
      RANGE=12.
      E1=FSIMP(FUNC,RANGE,61)
      GO TO 20
31    DO 41 J=1,61
41    FUNC(J)=FDAM2(J)*UDAM(J)
C
      RANGE=12.
      E2=FSIMP(FUNC,RANGE,61)
      GO TO 20
32    DO 42 J=1,61
      RANGE=60.
42    FUNC(J)=FPOW1(J)*UPOW(J)
      E3=FSIMP(FUNC,RANGE,61)
33    DO 43 J=1,61
43    FUNC(J)=FPOW2(J)*UPOW(J)
      RANGE=60.
      E4=FSIMP(FUNC,RANGE,61)
      GO TO 20
34    E5=8.17
      GO TO 20
35    E6=2.20
20    CONTINUE
      DES1=E1+E3+E5
      DES2=E2+E4+E6
C
C     OUTPUT
C
      WRITE(6,100)
100   FORMAT(/,1H ,15X,24HEXPECTED VALUES OF VALUE,//)
      WRITE(6,101)
101   FORMAT(/,1H ,12X,6HDAMAGE,7X,5HPOWER,9X,5HPARTS,8X,5HTOTAL,//)
      WRITE(6,102)E1,E3,E5,DES1
102   FORMAT(/,1H ,8HDESIGN 1,4X,F5.3,8X,F5.3,9X,F5.3,8X,F6.3)
      WRITE(6,103)E2,E4,E6,DES2
103   FORMAT(/,1H ,8HDESIGN 2,4X,F5.3,8X,F5.3,9X,F5.3,8X,F6.3)
10    FORMAT(16F5.2)
11    FORMAT(F5.0)
      STOP
      END
SUBROUTINE FSIMP

      FUNCTION FSIMP(FUNC,RANGE,MINT)
C.... CALCULATES INTEGRAL BY SIMPSONS RULE WITH
C     MODIFICATION IF MINT IS EVEN
C.... INPUT
C        FUNC = ARRAY OF EQUALLY SPACED VALUES OF FUNCTION
C               DIMENSION MINT
C        RANGE = RANGE OF INTEGRATION
C        MINT = NUMBER OF STATIONS
C.... OUTPUT
C        FSIMP = AREA
      DIMENSION FUNC(1)
C.... CHECK MINT FOR ODD OR EVEN
      XX=RANGE/(3.*FLOAT(MINT-1))
      M=MINT/2*2
      IF(M.EQ.MINT) GO TO 3
C.... ODD
      AREA=FUNC(1)+FUNC(M)
      MM=MINT-1
      DO 1 I=2,MM,2
1     AREA=AREA+4.*FUNC(I)
      MM=MM-1
      DO 2 I=3,MM,2
2     AREA=AREA+2.*FUNC(I)
      FSIMP=XX*AREA
      RETURN
C.... EVEN
C.... USE SIMPSONS RULE FOR ALL BUT THE LAST 3 INTERVALS
3     M=MINT-3
      AREA=FUNC(1)+FUNC(M)
      MM=M-1
      DO 4 I=2,MM,2
4     AREA=AREA+4.*FUNC(I)
      MM=MM-1
      DO 5 I=3,MM,2
5     AREA=AREA+2.*FUNC(I)
      FSIMP=XX*AREA
C.... USE NEWTONS 3/3 RULE FOR LAST THREE INTERVALS
      FSIMP=FSIMP+9./3.*XX*(FUNC(MINT-3)+3.*(FUNC(MINT-2)+FUNC(MINT-1))
      1 +FUNC(MINT))
      RETURN
      END

enter image description here

1 个答案:

答案 0 :(得分:0)

以下是帮助您入门的最小示例:

C Minimal working example of creaky old FORTRAN I/O
      PROGRAM ABYSS
      IMPLICIT NONE
C
      REAL FDENS(61)
      REAL XRANGE
      INTEGER J
C
10    FORMAT(16F5.2)
11    FORMAT(F5.0)

909   FORMAT(/, 'BEHOLD! A DENSITY DISTRIBUTION',/)
910   FORMAT(10(F5.2, 3X),/)
911   FORMAT(/, 'XRANGE is ', F6.1)
C
      CONTINUE
C
      READ(5,10) (FDENS(J), J=1,61)
      READ(5,11) XRANGE
C
      WRITE(6,909)
      WRITE(6,910) (FDENS(J), J=1,61) 
      WRITE(6,911) XRANGE
C
      STOP
      END

在F77中写这篇文章的道歉;为了这个例子,我坚持上面发布的代码的风格。理想情况下,您可以使用F03或F08作为新代码或完全不同的语言,它实际上具有良好的I / O功能和丰富的标准库。但我离题了。

此代码将对数据进行操作(注意保留空格):

                               0.1  0.3  0.5  0.9  1.30 1.90 2.50 3.20 3.80 4.20
 4.70 5.0  5.1  5.2  5.2  5.1  4.9  4.7  4.6  4.4  4.2  3.9  3.8  3.6  3.4  3.2 
 3.0  2.9  2.7  2.5  2.4  2.2  2.1  1.9  1.8  1.6  1.5  1.4  1.2  1.1  1.0  0.9 
 0.8  0.7  0.6  0.5  0.4  0.3  0.3  0.2  0.1  0.1                
 12.

生产

BEHOLD! A DENSITY DISTRIBUTION

 0.00    0.00    0.00    0.00    0.00    0.00    0.10    0.30    0.50    0.90

 1.30    1.90    2.50    3.20    3.80    4.20    4.70    5.00    5.10    5.20

 5.20    5.10    4.90    4.70    4.60    4.40    4.20    3.90    3.80    3.60

 3.40    3.20    3.00    2.90    2.70    2.50    2.40    2.20    2.10    1.90

 1.80    1.60    1.50    1.40    1.20    1.10    1.00    0.90    0.80    0.70

 0.60    0.50    0.40    0.30    0.30    0.20    0.10    0.10    0.00    0.00

 0.00

XRANGE is   12.0

如果代码在abyss.f中,输入数据在abyss.dat,您应该可以使用

构建代码
gfortran -g -Wall -Og -o abyss abyss.f

并通过运行

生成类似的结果
abyss < abyss.dat > abyss.out

要注意的一个要点是原始代码是从单元5(传统上被视为stdin读取,现在在iso_fortran_env中正式标榜为INPUT_UNIT)。在您自己的代码中,我建议您从数据文件中读取内容,因此请将文字5替换为包含您要读取的文件的单元号的任何变量(提示:请考虑使用{ {1}} Fortran 2008中引入的newunit命令的参数。它解决了常常愚蠢的Fortran问题,试图找到一个免费的I / O单元号。)虽然你可以使用I / O重定向,但它是&#39} ;次优;它用于说明如何解决原始代码的限制。

另外,为了后代和你自己的理智,请避免利用冷战时代的FORTRAN错误特征,例如这个空间等于零的废话。如果您的数据值得使用,那么值得采用一种易于解析的合理格式;柱状,空格分隔的值与任何选择一样好。 Fortran实际上可以获得一个标准库,可以在2156年左右读取和写入CSV文件(给出或花费一个世纪),这样你就有足够的时间来设计一些体面的东西......