1、文件读写操作,对于用户来讲按照文件类型可以分为文本文件和二进制文件两种,在使用OPEN或者WRITE函数进行读写时首先要明确的是要操作的文件的类型,另外FORTRAN可以按顺序读写,同样可以直接读写,直接读写类似于我们用CD机听音乐时可以直接跳到我们要听的部分。读写函数一OPEN函数为例:
open(unit=fileid, file=filename, access="direct",recl=4, status="replace")
表明要读的文件名称为filename的文件,采用直接读取方式,一次读取的文件容量是4字节,status=“replace”表明文件存在就覆盖,不存在就创建新的文件。
WRITE/OPEN(UNIT=number,FMT=format,NML=namelist,REC=record,IOSTAT=stat,ERR=errlable,END=endlabel)
UNIT指定READ/WRITE所用的输入输出位置,注意一般避免用1,5,2,6,因为上述为默认的输入和输出即键盘和屏幕。
FMT是输入输出格式化字符
REC是在直接读写中设置要读写的文件块的位置
另外一个例子如下:直接读写文本文件list.txt,值得注意的是open函数中recl=6,这里是因为list文本中每一行只有一个浮点数记录,占4个字节,但是由于在微软的操作系统中文本文件每行结尾有两个看不见的符号表示文件当行结束,因此每行记录是4+2,这个数值在UNIX系统中是4+1,因为UNIX系统只需一个字符表示当前行结束标志。
program ex0910
implicit none
integer, parameter :: fileid = 10
character(len=20) :: filename = "list.txt"
integer player
real hit
integer error
logical alive
......
......
open(unit=fileid, file=filename, access="direct",form="formatted", recl=6, status="old")
do while(.true.)
write(*,"('查询第几棒?')")
read (*,*) player
read(fileid, fmt="(F4.2)", rec=player, IOSTAT=error) hit
if ( error/=0 ) exit
write(*,"('打击率:'F4.2)") hit
end do
close(fileid)
stop
end program
2、用INQUIRE查询文件的状态,下面的例子用来检查文件名为ex0903.f90的文件是否存在。
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
end
当然INQUIRE使用方法很多 ,
INQUIRE(UNIT=number,FILE=filename,IOSTAT=stat,ERR=errlable,EXISIT=exist,OPENED=opened,ACCESS=access,DIRECT=direct)。
请注意上述有的是字符串类型例如direct、access等有的为逻辑值如exist和opened。
3、字符串变量文件,作用是把数据写到一个字符串变量中,例如:
program ex0914
implicit none
integer :: a=2
integer :: b=3
character(len=20) :: string
write( unit=string, fmt="(I2,'+',I2,'=',I2)" ) a,b,a+b
write(*,*) string
stop
end program
执行结果是2+3=5;
应为有的时候我们要从键盘输入数值给程序,但是不小心输入了字母等会造成意想不到的错误结果,为了检查我们从键盘的输入结果就可以使用 暂时把数据当字符串,然后调用函数检查这个字符串,若都是数字字符,就把它转化为整数。
另外一个用法是动态改变字符串内容的输入输出格式下面是一个例子:
program ex0917
implicit none
integer a,b
character(len=20) :: string
character(len=20) :: fmtstring="(I??'+'I??'='I??)"
integer,external::GetInteger
a=GetInteger()
b=GetInteger()
write(fmtstring(3:4),"(I2.2)") int(log10(real(a))+1) !计算数字a的数值位数,并修改格式化字符串
write(*,"('a:',A20)") fmtstring !输出修改的格式化字符串
write(fmtstring(9:10),"(I2.2)") int(log10(real(b))+1) !计算b的位数,然后修改格式化字符串
write(*,"('b:',A20)") fmtstring !输出修改的格式化字符串
write(fmtstring(15:16),"(I2.2)") int(log10(real(a+b))+1) !计算a+b结果的位数修改格式化字符串
write(*,"('a+b:',A20)") fmtstring
write(*,fmtstring)a,b,a+b
stop
end program
integer function GetInteger()
implicit none
character(len=80) :: string
logical :: invalid
integer i, code
invalid = .true.
do while( invalid )
write(*,*) "输入正整数"
read(*, "(A80)" ) string
invalid = .false.
do i=1, len_trim(string)
code = ichar(string(i:i))
if ( code<ichar('0') .or. code>ichar('9') ) then
invalid=.true.
exit
end if
end do
end do
read( string, * ) GetInteger
return
end function
运行结果
4、NAMELIST
FROTRAN90统一了NAMELIST的标准,可以把一组相关的变量封装在一起,在输入输出时只要在WRITE中NML字段赋值哪一个NAMELIST就行了,例如:
program ex0918
implicit none
integer :: a = 1, b = 2, c = 3
namelist /na/ a,b,c !把变量abc放到名字为na的NAMELIST ,是声明的一部分
write(*,nml=na) !输出na封装的变量
stop
end program
执行后的结果
&NA
A = 1, !输出变量名 等号 数值
B = 2,
C = 3
/ !最后用/号最为结束
NAMELIST一可以用来输入变量值,但要注意输入变量值时采用的固定格式:以&开头以/结束,例如
program ex0919
implicit none
integer :: a, b, c
namelist /na/ a,b,c
read (*,nml=na)
write(*,nml=na)
stop
end program
输入时可以不必按照变量声明的顺序,例如 &NA a=1 c=3/ 。
同样可以从文本文件中读取NAMELIST的内容。