Fortran命令
Fortran之open函数
1.文件读取的概念:
读取:“顺序读取”和“直接读取”。
保存:“文本文件”和“二进制文件”。
二进制文件:读取快,因为保存格式和数据在内存中的保存方法一样,同时也节省空间。----------------------------------
2. 文件的操作:
----------------------------------
open的使用:使用open命令打开文件之后,就可以对文件来做输入输出。example:
program ex0901
impicit none
open(unit=10, file='hello.txt') ! 打开hello.txt文件, unit指定文件代码,file指定文件名称。
write(10, *) "hello" !在代码为10的文件中写入hello
stop
end program ex0901
open中有很多参数可以使用,详细如下:
OPEN(UNIT=number, FILE='filename', FORM='...', STATUS='...', ACCESS='...', R ECL=length, ERR=label, IOSTAT=iostat, BLANK='...', POSITION='...', ACTION=ac tion, PAD='...', DELIM='...')
UNIT='number':number必须是一个正整数,它可以使用变量或是常量来赋值。numbe r最好避开1,2,5,6。因为2,6是默认的输出位置,也就是屏幕。1,5则是默认的输入位置,键盘。
FILE='filename':指定要打开的文件名称,文件名要符合系统规定。windows下不区分大小写,unix下则会区分大小写,最好不要使用中文文件名。
FORM='FORMATTED' OR 'UNFORMATTED'
FORM字段只有两个值可以设置:
FORM='FORMATTED' “文本文件”格式来保存
FORM='UNFORMATTED' “二进制文件”格式保存
这一栏不给定时候的默认值是: FORM='FORMATTED'
STATUS='NEW' or 'OLD' or 'SCRATCH' or 'UNKNOWN' 用来说明打开一个新的文件或已经存在的旧文件。
STATUS='NEW' 打开一个原本不存在的新文件
STATUS='OLD' 打开一个原来已经存在的文件
STATUS='REPLACE' 若文件已经存在则重新创建一次,原来的内容消失;若不存在则会
创建新文件。
STATUS='SCRATCH' 表示要打开一个暂存文盘,这个时候可以不需要指定文件名称,也就是FILE这个一栏可以忽略。因为程序本身会自动取一个文件名,至于文件名是啥也不重要,因为暂存盘会在程序结束后自动删除。
STATUS='UNKNOWN' 由各编译器自定义。通常会同REPLACE的效果。
!这一栏不给定时,默认为STATUS='UNKNOWN'。
ACCESS='SEQUENTIAL' or 'DIRECT' 设置读写文件的方法:
ACCESS='SEQUENTIAL' 读写文件的操作会以“顺序”的方法来做读写,“顺序读取文件”。
ACCESS='DIRET' 读写文件的操作可以任意指定位置,“直接读取文件”。
!不赋值时候,默认为:ACCESS='SEQUENTIAL'。
RECL=length 在顺序读取文件中,RECL字段值用来设置一次可以读取多大容量的数据。打开“直接读取文件”,RECL=length的length值是用来设置文件中每一个模块单元的分区长度。
length的单位在文本根式下为1个字符,也就是1 byte。在二进制格式下则由编译器自行决定,一般可能为1 byte (G77) 或4 byte (Visual Fortran)。
ERR=LABEL这个字段用来设置当文件打开发生错误时,程序会跳跃到LABEL所指定的行代码处来继续执行程序。
IOSTAT=var 这个字段会设置一个整数值给后面的整型变量,这是用来说明文件打开的状态,数值会有下面三种情况:
var>0 表示读取操作错误
var=0 表示读取操作正常
var<0 表示文件终了
BLANK='NULL' or 'ZERO' 用来设置输入数字时,当所设置的格式字段中有空格存在时所代表的意义。
BLANK='NULL'时,空格代表没有东西。BLANK='ZERO'时,空格部分会自动以0代入。以下是Fortran 90添加的功能:
POSITION='ASIS' or 'REWIND' or 'APPEND' 设置文件打开时候的读写位置:POSITION='ASIS' 表示文件打开时的读取的位置不特别指定,通常就是在文件的开头。是默认值。
POSITION='REWIND' 表示文件打开时的读取位置移到文件的开头。POSITION='APPEND' 表示文件打开时的读取位置移到文件的结尾。
ACTION='READ' or 'WRITE' or 'READWRITE' 设置打开文件的读写权限:ACTION='READWRITE' 表示所打开的文件可以用来读取及写入,这是默认值。ACTION='READ' 表示所打开的文件只能用来读取数据。
ACTION='WRITE' 表示所打开的文件只能用来写入数据。
PAD='YES' or 'NO'
PAD='YES' 在格式化输入时,最前面的不足字段会自动以空格填满,默认值是PAD='YE S'。
PAD='NO' 在格式化输入时,不足的字段不会自动以空格填满。
DELIM='APOSTEROPHE' or 'QUOTE' or 'NONE'
DELIM='NONE' 纯粹输出字符串内容
DELIM='QUOTE' 输出字符串内容会在前后加上双引号
DELIM='APOSTEROPHE' 输出字符串内容会在前后加上单引号
-----------------------------------------
WRITE & READ的使用(详细):
WRITE/READ(UNIT=number, FMT=format, NML=namelist, REC=record, IOSTAT= stat, ERR=errlabel, END=endlabel, ADVANCE=advance, SIZE=size)
UNIT=number 指定read/write所使用的输入输出的位置。
FMT=format 指定输入输出格式的使用。
NML=namelist 指定读写某个NAMELIST的内容(后续介绍)。
REC=record 在直接读取文件中,设置所要读写的文件的模块位置。
IOSTAT=stat 会设置一个数值给在它后面的变量,用来说明文件的读写状态。
stat>0 表示读取操作发生错误。
stat=0 表示读取操作正常。
stat<0 表示文件终了。
ERR=errlabel 指定在读写过程中发生错误时,会转移到某个行代码来继续执行程序。END=endlabel 指定在读写到文件末尾时,要转移到某个行代码来继续执行程序。
以下是fortran 90添加功能:
ADVANCE='YES' or 'NO' 设置在文本格式下的顺序文件中,每一次的READ,WRITE命令完成后,
读写位置会不会自动想下移动一行。
ADVANCE='YES' 是默认的状态,每读写一次会向下移动一行。
ADVANCE='NO' 会暂停自动换行的操作。
!使用这个字段时候一定要设置输出入格式,在屏幕输出时可以使用这个设置来控制w rite命令是否会自动换行。
SIZE=count 在ADVANCE='NO'时,才可以使用这个字段。它会把这一次输出入的字符数目设置给后面的整型变量。
----------------------------------
查询文件的状态INQUIRE:
在使用open打开文件的前后,都可以通过inquire命令来查询文件目前的情况,inquire命令中的各个字段和第一小节中open的字段很类似。
example: !检查某个程序是否存在
program ex0903
implicit none
character(len=20) :: filename = "ex0903.f90"
logical alive
inquire(file=filename, exist=alive)
if(alive) then
write (*, *) filename, " exist."
else
write (*, *) filename, "doesn't exist."
end if
stop
edn program ex0903
详细介绍inquire的使用方法:
INQUIRE(UNIT=number, FILE=filename, IOSTAT=stat, ERR=label, EXIST=exist, OPENED=opened, NUMBER=number, NAMED=named, ACCESS=access, SEQUENT IAL=sequential, DIRECT=direct, FORM=form, FORMATTED=formatted, UNFORM ATTED=unformatted, RECL=recl)
UNIT=number 文件代号
FILE=filename 文件名
IOSTAT=stat 查询文件读取情况,会设置一个整数给后面的变量:
stat>0 文件读取操作错误
stat=0 文件读取操作正常
stat<0 文件终了
ERR=errlabel 发生错误时会转移到复制的代码行继续执行程序。
EXIST=exist 检查文件是否存在,返回布尔变量,真表示存在,假值表示不存在。OPEND=opened 检查文件是否用已经用open打开,返回布尔变量,真表示已经打开,假表示尚未打开。
NUMBER=number 用文件名来查询这个文件所给定的代码。
NAMED=named 查询文件是否取了名字,也就是检查文件是否为临时保存盘,返回值为逻辑数。
ACCESS=access 检查文件的读取格式,返回一个字符串,可以是:
'SEQUENTIAL' 代表文件使用顺序读取格式
'DIRECT' 代表文件使用直接读取格式
'UNDEFINED' 代表没有定义
SEQUENTIAL=sequential 查看文件是否使用顺序格式,会返回一个字符串,可以是:'YES' 代表文件是顺序读取文件
'NO' 代表文件不是顺序读取文件
'UNKNOWN' 代表不知道
DIRECT=direct 查看文件是否使用直接格式,会返回一个字符串,可以是:'YES' 文件是直接读取文件
'NO' 文件是非直接读取文件
'UNKNOWN' 代表不知道
FORM=form 查看文件的保存方法,返回字符串,可以是:
'FORMATTED' 打开的是文本文件
'UNFORMATTED' 打开的是二进制文件
'UNDEFINED' 没有定义
FORMATTED=fmt 查看文件是否是文本文件,返回字符串,可以是:
'YES' 本文件是文本文件
'NO' 本文件非文本文件
'UNDEFINED' 无法判断
UNFORMATTED=fmt 查看文件是否是二进制文件,返回字符串,可以是:'YES' 本文件是二进制文件
'NO' 本文件非二进制文件
'UNKNOWN' 无法判断
RECL=length 返回open文件时recl栏的设置值。
NEXTREC=nr 返回下一次文件读写的位置。
BLANK=blank 返回值是字符串,用来查看open文件时的blank参数所给定的字符串值。以下是fortran 90的添加功能:
POSITION=position 返回打开文件时position字段所给定的字符串, 可能是'RE WIND',
'APPEND', 'ASIS', 'UNDEFINED'
ACTION=action 返回打开文件时action 字段所赋值的字符串,可能是'READ', 'WR ITE',
'READWRITE'。
READ=read 返回字符串,检查文件是否为只读文件:
'YES' 文件是只读的
'NO' 文件不是只读的
'UNKNOWN' 无法判断
WRITE=write 返回一个字符串,检查文件是否可写入:
'YES' 文件可以写入
'NO' 文件不可以写入
'UNKNOWN' 无法判定
READWRITE=readwrite 返回一个字符串,检查文件是否可以同时读及写:
'YES' 文件可以同时读写
'NO' 文件不可以同时读写
'UNKNOWN' 无法判定
DELIM=delim 返回打开文件时,DELIM字段所设置的字符串,返回值可以是:'APOSTROPHE', 'QUOTE', 'NONE', 'UNDEFINED'
PAD=pad 返回打开文件时PAD字段所设置的字符串,返回值可以是:'YES', 'NO'。
其他文件运行命令:
BACKSPACE(UNIT=number, ERR=errlabel, IOSTAT=iostat) 把文件读写位置退回一步。
ENDFILE(UNNIT=number, ERR=errlabel, IOSTAT=iostat)使用这个命令会把目前文件的读写位置变成文件的结尾。
REWIND(UNIT=number, ERR=errlabel, IOSTAT=iostat)把文件的读写位置倒回到文
件开头。
CLOSE(UNIT=number, STATUS=string, ERR=errlabel, IOSTAT=) 把文件关闭,不要进行读写操作。
STAT='KEEP' 会在文件关闭后,保留这个文件。是默认状态。
STAT='DELETE' 在文件关闭后,消除这个文件。
-------------------------------------------
!程序结束时候会自动关闭文件,不过最好要养成自己关闭文件的习惯。
!在读文件的时候要懂得略掉一些没有必要的数据,如文件中的注释行。
!自由格式的数据文件读取(可以先读入前面的判断字符,结合select case或其他方法判断读入的数据)
!在open,read,write时使用不同的unit值,就可以打开多个文件。最好不要同时打开很多个文件。
顺序文件(SEQUENTIAL):在读写时,不能任意赋值到文件的某个位置读写数据,只能从开头开始一步步向下进行。在改变文件读写位置时,只能一步步地退,或是直接移回到文件开头。
直接访问文件:把文件的空间,内容,事先分区成好几个同样大小的小模块,这些模块会自动安顺序编号。读写文件时,要先赋值文件读写位置在第几个模块,再进行读写的工作。直接访问文件可以任意到文件的任何一个地方来读写。在使用直接访问文件时,要小心使用e ndfile命令,使用这个命令会把目前所在的文件位置之后的数据都清除掉。
二进制文件的操作:使用二进制文件来做直接读取时,open命令中的recl字段所设置的整数n值所代表的大小会随编译器不同而改变。每个编译器应该都可以经过设置来改变recl 字段的单位大小。二进制文件没有必要在数据之间用区分符号来增加文件的可读性,因为二进制文件本身就没有可读性。二进制文件是直接把内存的二进制数据写入文件,就没有所谓的格式化输入/出存在。存放“精确”及“大量”的数据时,使用二进制文件是比较好的选择。二进制文件也可以使用顺序格式来操作,顺序格式下显示来的二进制文件,每个数据的前后都会被编译器补上一些额外的信息,所生成的文件不太容易被其他程序读取。
关于以上文件操作详细见《fortran 95程序设计》9-3~9-5。
Internal File(内部文件)
使用写入文件的方法,把数据写到一个字符串变量中。
example:
a=2
b=3
character (len=20) :: string
write (unit=string, fmt="(I2,'+',I2,'=',I2)") a, b, a+b !把字符串变量当作输出的目的。write(*, *) string
结果: 2+ 3= 5
还可以经过read命令从字符串读入数据:
integer :: a
character (len=20) :: string="123"
read(string, *) a
write(*, *) a
在某些情况下需要使用内部文件来设置数据:
使用read命令从键盘输入数据时,如果用户输入错误的数据,会导致死机。如需要输入整数时却输入英文字母,就可能会死机。比较好的处理办法是,程序先暂时把数据当作字符串读入,检查字符串中是否含有不合理的字符,如果字符串中都是0~9的数字字符,就把字符串转成整数,不然就请用户在输入一次。
内部文件还可应用在动态改变输出格式,输出格式可以事先存放在字符串中,程序进行时,动态改变字符串内容就可以改变输出格式。(见书P263)
NAMELIST:
NAMELIST是很特殊的输入/输出方法,收录在f90标准当中,f90中有统一NAMELI ST的格式。
NAMELIST可以把一组相关变量封装在一起,输入/出这一组变量时,只要在write/rea d中的NML字段赋值使用哪一个NAMELIST就行了。
example:
program ex0918
implicit none
integer :: a = 1, b = 2, c= 3
namelist /na/ a,b,c
write(*,nml=na)
stop
end program ex0918
&NA
A = 1,
B = 2,
C = 3,
/
程序中把a,b,c这三个变量放在名字叫做na的namelist中。namelist也算是声明的一部分,必须编写在程序执行命令前面。
NAMELIST的语法很类似COMMON,不过使用namelist时一定要取名字:namelist /nl_name/ var1, var2, ... !后面的变量会放在nl_name这个namelist中。封装好namelist后,在write的NML字段中指名要输出哪一个namelist,就可以把name list中的变量全部输出。
write(*,nml=na) !输出na这个namelist
输出namelist时候不能赋值输出格式,f90标准中规定输出namelist时首先会输出符号&,后面紧接着这个namelist的名字。接着会根据顺序输出变量的名称,等号以及内容,变量之间用空格或逗号来做分隔,最后使用除号来作结束。
至于每个数值内容会使用何种格式输出由编译器自行决定。
NAMELIST也可以用来输入数据,不过通常都会用来读取文件,不会用在键盘输入。输入格式需要按照前面的格式。&na ....../ 不需要按照变量顺序输入,程序会自动按照变量名称来设置数值。变量甚至可以重复输入,不过变量会得到最后一次设置的数值。
namelist通常使用在文本文件的输入/输出中,使用read从文件中读取数据时,会自动从目前的位置向下寻找存放namelist的地方。
example:
program ex0920
implicit none
integer :: a(3)
namelist /na/ a
open(10, file="ex0920.txt")
read(10, nml=na)
write(*, "(3I2)") a
stop
end program
输入文件的内容如下:
happy birthday
&na a = 1,2,3/
程序打开时,读写位置在文件的开头,read命令会自动向下寻找na这个namelist的存放位置来读取数据,这边可以看到namelist处理数组的方法,它会在等号后面根据顺序显示数组内容。
FORTRAN 90 程序编程规范
FORTRAN 90 程序编程规范 Fortran 90 编程规范,使程序代码高度组织化,更加易读、易懂、易于维护,程序更加高效。使编出的程序更易懂、易于维护。 1 语言选择 数值预报创新系统软件开发应避免使用Fortran77 的某些过时特征以Fortran 90不一致的特征。选择Fortran 90 作为开发语言,并采用Fortran 90 的新功能,如动态内存的分配(dynamic memory allocation)、递归(recursion ), 模块(modules)、POINTER 、长变量名、自由格式等。 Fortran 77其中某些只是一些冗余的功能,这些功能已经过时,另外,还有一些在Fortran90 中被证明是不好的用法,建议不要使用。 2 Fortran 90 的新特性 2.1.1 建议使用的Fortran 90 新特性 建议使用Fortran 90 提供的模块(module ),并用Use ONLY 指定module 中哪些变量或派生类型定义可用于调用程序。 尽量使用数组下标三元组,这样可优化并减少所需的代码行数。为提高可读性,要在括号内表明数组的维数,例如: 1dArrayA(:) = 1dArrayB(:) + 1dArrayC(:) 2dArray(: , :) = scalar * Another2dArray(: , :) 当访问数组的子集时,例如在有限差分等式中,可以通过使用下标三元组实现。例如:2dArray(: , 2:len2) = scalar *( & Another2dArray(:, 1:len2 -1) & - Another2dArray(:, 2:len2) & ) 对程序单元(program units )命名,并使用End program ,End subroutine ,End interface ,End module 等结构再次指定“program unit ”的名称。 在逻辑表达式中使用>、 >=、 ==、 <、 <=、 /=,它们分别代 替.gt.、.ge.、.eq.、.lt.、.le.、.ne. 。新的表示方法更接近标准的数学符号 在变量定义中始终使用“::”;始终用“DIMENSION ”定义数组形状;始终用(len=)的语法格式声明字符变量的长度。
fortran语法手册
1 FORTRAN77四则运算符 + - * / ** (其中**表示乘方) 在表达式中按优先级次序由低到高为:+或-→*或/→**→函数→() 2 FORTRAN77变量类型 2.1 隐含约定:I-N规则 凡是以字母I,J,K,L,M,N六个字母开头的,即认为是整型变量,其它为实型变量。 如IMPLICIT REAL (I,J) 三种定义的优先级别由低到高顺序为:I-N规则→IMPLICIT语句→类型说明语句,因此,在程序中IMPLICIT语句应放在类型说明语句之前。 2.4 数组的说明与使用 使用I-N规则时用DIMENSION说明数组,也可在定义变量类型同时说明数组,说明格式为:数组名(下标下界,下标上界),也可省略下标下界,此时默认为1,例: DIMENSION IA(0:9),ND(80:99),W(3,2),NUM(-1:0),A(0:2,0:1,0:3) REAL IA(10),ND(80:99)使用隐含DO循环进行数组输入输出操作:例如WRITE(*,10) ('I=',I,'A=',A(I),I=1,10,2) 10FORMAT(1X,5(A2,I2,1X,A2,I4)) 2.5 使用DATA语句给数组赋初值 变量表中可出现变量名,数组名,数组元素名,隐含DO循环,但不许出现任何形式的表达式:例如 DATA A,B,C/-1.0,-1.0,-1.0/ DATA A/-1.0/,B/-1.0/,C/-1.0/ DATA A,B,C/3*-1.0/CHARACTER*6 CHN(10)
DATA CHN/10*' '/INTEGER NUM(1000) DATA (NUM(I),I=1,500)/500*0/,(NUM(I),I=501,1000)/500*1/ 3 FORTRAN77程序书写规则 程序中的变量名,不分大小写; 变量名称是以字母开头再加上1到5位字母或数字构成,即变更名字串中只有前6位有效; 一行只能写一个语句; 程序的第一个语句固定为PROGRAM 程序名称字符串 某行的第1个字符至第5个字符位为标号区,只能书写语句标号或空着或注释内容; 某行的第1个字符为C或*号时,则表示该行为注释行,其后面的内容为注释内容; 某行的第6个字符位为非空格和非0字符时,则该行为上一行的续行,一个语句最多可有19个续行; 某行的第7至72字符位为语句区,语句区内可以任加空格以求美观; 某行的第73至80字符位为注释区,80字符位以后不能有内容。 4 FORTRAN77关系运算符 .GT. 大于 .GE. 天于或等于 .LT. 小于 .LE. 小于或等于 .EQ. 等于 .NE. 不等于 .AND. 逻辑与 .OR. 逻辑或 .NOT. 逻辑非 .EQV. 逻辑等 .NEQV. 逻辑不等 运算符优先级由高到低顺序为:()→**→*或/→+或-→.GT.或.GE.或.LT. 或.LE.或.EQ.或.NE.→.NOT.→.AND.→.OR.→.EQV.或.NEQV 5 FORTRAN77语句
fortran程序案例题汇编(14道)
1.Fibonacci数列定义如下: F1=1 F2=1 F n=F n-1+F n-2 (n>2) 求Fibonacci数列的前30项。 integer f(30),i f(1)=1 f(2)=2 do i=3,30 f(i)=f(i-1)+f(i-2) enddo print*,f end 2.输入10个学生的总分,求每个学生的名次integer s(10),a(10),i,j do i=1,10 read*,s(i) enddo do i=1,10 a(i)=1 do j=1,10 if(s(i)