如何将数据读入数组

问题描述:

我从工程教科书中找到了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

+0

欢迎来到Stack Overflow。尽量保持你的文章简洁。避免问候和感谢。你的名字在你的图标后面。标题应该介绍由标签指示的问题,而不是广泛的主题。不要只重复标题中的标签。只需使用[tag:fortran]等相当通用和更广泛的标签,仅在必要时为特定版本添加标签才能区分或指示您不希望使用更新版本的任何解决方案。 –

+0

您询问的一些数组是在程序中自动计算的。另一个是读取'read'语句。你有输入数据格式的描述吗?如果是,请编辑问题以包含它。 –

+0

@VladimirF感谢您的回复。原始代码与数据列表可以在原始问题中显示的链接中找到。作者刚刚添加它在主代码下,这就是为什么我很困惑... – Andy

下面是一个小例子,以帮助您开始:

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 

一个关键点要注意的TE类似的结果是,原来的代码从单元5(传统上作为stdin,现在在iso_fortran_env正式册封为INPUT_UNIT)读取。在你自己的代码中,我建议从数据文件中读取,所以用任何变量包含你正在读取的文件的单元号替换文字5(提示:考虑使用Fortran中引入的open命令的newunit参数它解决了试图找到免费的I/O单元编号的常年愚蠢的Fortran问题。)虽然可以使用I/O重定向,但它并不理想,它在这里用来展示如何解决原始代码的限制。

另外,为了后人和你自己的理智,请避免利用冷战时代的FORTRAN误用,比如这个空间等于零的废话。如果您的数据值得使用,那么值得使用可以轻松解析的合理格式;柱状的,空格分隔的值与任何值一样是一个很好的选择。 Fortran实际上可能会得到一个标准库,它可以在2156年左右读取和写入CSV文件(需要花费一个世纪),因此您有足够的时间来设计一些体面的东西......

+1

*在F77中写道这个道歉,但你无法抗拒那个'IMPLICIT NONE'! –

+0

看,只是因为我在F77中编写它并不意味着我必须将它写入/ bad/F77;) – arclight