Read 的规则:
按行读取,每次读一行,读完后光标自动跳到下一行的开头,空格和逗号代表结束(所以空格和逗号也是读取的一部分的话,需要使用“输入输出格式”)
如果想要将一行数据读入数组,代码为:
Read(10,*) s(:,:,:)
不用规定输入输出格式,因为会根据s(:,:,:)确定需要读入的数字的个数,然后fortran会按部就班的读取,甚至文件中当前这一行的数字个数不足以填满s(:,:,:)的时候,read会自动跳到下一行继续搜索数字,直到填满s(:,:,:)为止。
但是需要注意给数组赋值的顺序:read会把它搜索到的第一个数字给s(1,1,1),第二个给s(2,1,1),第三个给s(3,1,1)…
程序9 1: 将read(unit=field,fmt="(A79)",iostat=status)buffer 中的A79改为A2,结果只输出每行的前两个字符,说明read是按整行整行读取的。
中间空了几行之后,空行之后的内容还是能被读取和输出,这说明,空行和空白是不一样的:空行也算是一种文本内容,因此不会终止读取,而空白意味着结束。
!读取文件
program main
implicit none
character(len=79)::filename="number.txt",buffer
integer,parameter::field=10
integer::status=0
logical alive
inquire(file=filename,exist=alive)
if(alive)then
open(unit=field,file=filename)
do while(.true.)
read(unit=field,fmt="(A79)",iostat=status)buffer
if(status/=0)exit
write(*,"(A79)")buffer
end do
else
write(*,*)filename,"does't exist."
end if
pause
stop
end program main
=============================================
附number.txt
===============================
1234555666
879789789789789
二)Fixed Format(固定格式)
扩展名:.F 或 .FOR
1标号区:第l-5列
可以写l至5位整数。也可以没有标号。标号区中的空格不起作用。如lOO与100 或1 0 0作用相同。标号应是无符号整数(无正负号或小数点)。标号大小顺序没有任何要求。假如第二行的标号为1000,第三行的标号可以是10,也可以是99999。
标号区内不得出现标号以外的内容,但注释行例外。注释行的内容可以写在标号区内,一行中第一列为C或*的,该行即被认为注释行,编译时对该行内容不作翻译,对程序运行不产生任何影响。如果在第一列上出现的不是数字、空格或C和*的字符,编译时按出错处理。
2续行区:第6列
如果在一行的第6列上写一个非空格和非零的字符,则该行作为其上一行的续行。注意在某些系统中,这个字符可以不限于上面所列的,如 @ } ] ~ 等字符均可使用。F77允许一个语句有19个续行(即一个语句最多可以写成20行)。有的程序中第6列上用“l”,“2”,…表示该行是第1个或第2个续行,但用数字字符容易与第7列的数字形成连续的数字串而引起错觉,故最好使用固定的特殊字符。
3语句区:第7-72列
不要求一定从第7列开始写语句,可以从第7列以后(72列以前)的任何一列开始写,但一行只能写一个语句。如果写满了72列,一旦在终端上修改程序时在该行又插入了一些字符,就会使本行最后几个字符超出语句区而引起意料不到的错误。特别注意到语句最后的空格将可能溢出72列,在某些计算机系统上将导致难以查出的错误。应注意,引号内的字符串中所包括的空格是有效的,不能忽略。
4注释区:第73-80列
在卡片输入法时代,程序员一般利用此8列为程序行编序号以便查找。注释区只对程序员提供辨别信息,不是语句的一部分,在编译时不对72-80列作处理。
程序 9 2 将成绩输入date.txt
module typedef
type student
integer Chinese,English,Math
end type
end module
program main
use typedef
implicit none
integer::students
type(student),allocatable::s(:)
integer,parameter::fileid=10
character(len=80)::filename="date.txt"
integer::i
write(*,*)"how many students?"
read(*,*)students
allocate(s(students),stat=i)
if(i/=0)then
write(*,*)"allocate buffer fail"
stop!此处要学习跳出程序。
end if
open(fileid,file=filename)
do i=1,students
write(*,"('input the',I2,'th student''s scores')")i
read(*,*)s(i)%Chinese,s(i)%English,s(i)%Math !Sb了,其实可以直接写成s(i)
write(fileid,"('Student Number:',I2,/,'Chinese Score:',I3,'English Score:',I3,'Math Score:',I3)")i,s(i)!s(i)的三项可以分别设置各自格式,另外注意括号里封装字符用单引号
end do
close(fileid)
pause
stop
end program main
程序9 3 读取date.txt并且输出
module typedef
type student
integer Chinese,English,Math
end type
end module
program main
use typedef
implicit none
integer,parameter::fileid=10
integer::students
integer::n
type(student)::s
character(len=10)::filename="date.txt"
logical::alive
integer::stat=0
inquire(file=filename,exist=alive)
if(.not.alive)then
write(*,*)"file doesn'nt exist"
stop
end if
open(unit=fileid,file=filename)
do while(stat==0)
read(fileid,"(16XI2,/,14XI3,14XI3,11XI3)",iostat=stat)n,s !不知道为什么不能写作unit=fileid write(*,"('序号:',I2,'语文:',I3,'英语:',I3,'数学:',I3,I3)")n,s,stat
end do
pause
stop
end program main
程序9 5,跳跃读取:还是不太懂REC的用法
program main
implicit none
character(len=80)::filename="list.txt"
integer::fileid
logical::alive
integer::stat
integer::player
real::score
inquire(file=filename,exist=alive)
if(.not.alive)then
write(*,*)"file doesn't exist"
stop!体会stop的用法,用于在程序中间终止程序。end if
open(unit=fileid,file=filename,access="direct",&
form="formatted",recl=7,status="old")
do while(.true.)
write(*,*)"查询第几棒?"
read(*,*)player
read(fileid,"(F5.2)",rec=player,iostat=stat)score if(stat/=0)exit
write(*,"(F5.2)")score
end do
pause
stop
end program main
程序 9 6 内部变量的应用:本程序中invalid很好!否则我只能通过监视内层那个do的循环的次数来判断strng中的所有字母是不是检验完毕,本程序中的invalid这个变量显然更简单巧妙,先设置.true.进入外循环,然后.false.假设输入的都是正确的,可以跳出,然后用if“考验”这个假设。。。。。。。很巧!另外,本计算机能接受的最大整数是4byte、32bits,即2147483647。默认的也是长整型,即kind=4。
program main
implicit none
integer::i
integer,external::GetInteger
i=GetInteger()
write(*,*)i
pause
stop
end program main
integer function GetInteger()
implicit none
character(len=80)::string
integer::i,code
logical::invalid=.true.
do while(invalid)
write(*,*)"请输入整数"
read(*,"(A80)")string
invalid=.false.
do i=1,len_trim(string)
code=ichar(string(i:i)) !用code代替,增加可读性 2.string(i:i)不是string(i) if(code
write(*,*)"invalid input"
invalid=.true. !invalid这个逻辑变量用得非常巧妙,认真体会。。。而不是通过计数来终止exit
end if
end do
end do
read(string,*)GetInteger !GetInteger=string是不行的,会提示错误“the binary(二进制)expression operation is invalid for the data types of the two operands”要用read
end function GetInteger
程序9 7
module typedef
type student
integer Chinese,English,Math,Natural,Social
end type
end module
program main
use typedef !注意位置要在implicit none之前
implicit none
character,parameter::filename="grades.txt"
integer,parameter::fileid=10,students=20
character(len=80)::tempstr !目的是让read走过第一行
type(student)::s(students)
type(student)::mean=student(0,0,0,0,0) !用于计算各科平均分
integer::total(20),zongfen=0 !计算每个人的总分和所有人的所有成绩的总分
integer stat
integer::i,n
open(fileid,file="grades.txt",iostat=stat) !为什么file=filename就不成功!!!!
if(stat/=0)then
write(*,*)"file doesn't exist"
stop
end if
read(fileid,*)tempstr
do i=1,students
read(fileid,"(6I5)")n,s(i)%Chinese,s(i)%English,s(i)%Math,s(i)%Natural,s(i)%Social !mean=mean+s(i) !试验一下能不能合写,结果不能
mean%Chinese=mean%Chinese+s(i)%Chinese
mean%English=mean%English+s(i)%English
mean%Math=mean%Math+s(i)%Math
mean%Natural=mean%Natural+s(i)%Natural
mean%Social=mean%Social+s(i)%Social
total(i)=s(i)%Chinese+s(i)%English+s(i)%Math+s(i)%Natural+s(i)%Social
zongfen=zongfen+total(i)
end do
write(*,"('座号',1X,'语文',1X,'英语',1X,'数学',1X,'自然',1X,'社会',1X,'总分')")
do i=1,students
write(*,"(7I5)")i,s(i),total(i)
end do
write(*,"('平均分',6F6.1)")real(mean%Chinese)/20.0,real(mean%English)/20.0,&
real(mean%Math)/20.0,real(mean%Natural)/20.0,&
real(mean%Social)/20.0,real(zongfen)/20.0 !real(整形,实型,复型)
pause
stop
end program main
=======================================================================
程序9 7 修改版:关于read的使用,以前的理解是正确的,即read的读写位置会自动向下移动一行(因为ADVANCE的默认值是“YES”)。那么程序中read(fileid,"(6I5)")n,s(i)会导致双行读取是为什么呢?因为,每次读取共要读取7个量,而grade.txt中每行只有6个,所以对于第七个量,read很智能的自动从下一行读取,然后读取结束,读取位置跳到第三行开头。所以下一次读取的时候,是从第三行读取,这样就导致了一次读取要读两行。其实"(6I5)"直接用*代替就行,其效果是一样的。改正的方法是在grade.txt的每一行后随便加一个数字,充作第七个数。或者只读六个数。
====================================================
module typedef
type student
integer Chinese,English,Math,Natural,Social
integer Total !将每个学生的总分项加入type中,逻辑更清晰
end type
end module
program main
use typedef !注意位置要在implicit none之前
implicit none
character(len=80)::filename="grades.txt" !别弄成character,parameter(len=80)
integer,parameter::fileid=10
integer,parameter::students=20 !分开写,“道不同不相为谋”。而且首先声明的应该是常量,逻辑清晰
type(student)::s(students)
type(student)::mean=student(0,0,0,0,0,0) !用于计算平均分
character(len=80)::tempstr !目的是让read走过第一行
integer stat,i,n !用于控制过程的“过程变量”集合在一起,写在最后
open(fileid,file=filename,iostat=stat)
if(stat/=0)then
write(*,*)"file doesn't exist"
stop
end if
read(fileid,*)tempstr
do i=1,students
read(fileid,*)n,s(i)%Chinese,s(i)%English,s(i)%Math,s(i)%Natural,s(i)%Social!read到底是怎
么读的?为什么刚刚写成read(fileid,"(6I5)")n,s(i)的时候会两行两行的读取?
s(i)%Total=s(i)%Chinese+s(i)%English+s(i)%Math+s(i)%Natural+s(i)%Social !mean=mean+s(i) !试验一下能不能合写,结果不能
mean%Chinese=mean%Chinese+s(i)%Chinese
mean%English=mean%English+s(i)%English
mean%Math=mean%Math+s(i)%Math
mean%Natural=mean%Natural+s(i)%Natural
mean%Social=mean%Social+s(i)%Social
mean%Total=mean%Total+s(i)%Total
end do
write(*,"(7A7)")"座号","语文","英语","数学","自然","社会","总分"!这说明格式不只是赋给abcd之类的变量的,像"语文"这样的量也可以享受“格式”
do i=1,students
write(*,"(7I7)")i,s(i)
end do
write(*,"(A7,6F7.1)")"平均分",real(mean%Chinese)/20.0,real(mean%English)/20.0,&
real(mean%Math)/20.0,real(mean%Natural)/20.0,&
real(mean%Social)/20.0,real(mean%Total)/20.0 !real(整形,实型,复型)
pause
stop
end program main
!现在有一个常出现的问题是:在定义fileid和filename这两个变量之后,常出现“断点”错误,跳来跳去program main
implicit none
integer,parameter::fileid=10
integer,parameter::buffer_size=256*256
character(len=80)::filename="lena.raw" !别忘了要定义len=80,另外parameter好像不能定义长度character::cbuffer(buffer_size)
integer::ibuffer(buffer_size)
integer::i,j=1,stat
open(fileid,file=filename,recl=buffer_size/4,access="direct",status="old",iostat=stat)
if(stat/=0)then
write(*,*)"file doesn't exite"
stop!别忘了stop啊,怎么这么不长记性呢!!!不是人家fileid和filename的原因,是这里少了stop 啊!!
end if
!do i=1,buffer_size 傻叉了吗,还do呢,全部读取就行了呗
read(fileid,rec=1)cbuffer!只有文本文件顺序读取是,才会“按行操作”
close(fileid)
do i=1,buffer_size
if(ichar(cbuffer(i))>=127)then
j=j+1
end if
ibuffer(i)=ichar(cbuffer(i))
end do
write(*,*)j !彭国伦是错的, j为20547,说明ichar的返回值范围为0~255。
do i=1,buffer_size
cbuffer(i)=char(255-ibuffer(i))
end do
open(fileid,file=filename,recl=buffer_size/4,access="direct",status="replace",iostat=stat) write(fileid,rec=1)cbuffer
close(fileid)
pause
stop
end program main
程序9 9 :最初的问题出现在我自己写的txt文件上:没有行结束标志,所以整个文件虽然非常大但只有一
program main
implicit none
character(len=79)::filename="9 9.txt" integer,parameter::fileid=10
integer::stat
character(len=79) temp
integer::count=0
open(unit=fileid,file=filename,iostat=stat) if(stat/=0)then
write(*,*)"file doesn't exist"
stop
end if
do while(.true.)
read(fileid,"(A79)",iostat=stat)temp
if(stat/=0)exit
write(*,*)temp
count=count+1 !判断是否满屏的程序
if(count==24)then
count=0
pause
end if
end do
程序9 10
!字符串和数组还是有区别的:同样在部分赋值的情况下,输出字符串没有问题,输出数组可能“未赋值部分”也会输出,为随机数。
program main
implicit none
character(len=80)::filename="encode1.txt"
integer::fileid=10
character(len=79) temp
integer i
integer stat
open(fileid,file=filename,iostat=stat)
if(stat/=0)then
write(*,*)"filename doesn't exist"
stop
end if
do while(.true.)
read(fileid,"(A79)",iostat=stat)temp
if(stat/=0)exit
do i=1,len_trim(temp)
temp(i:i)=char(ichar(temp(i:i))-3)
end do
write(*,*)temp
end do
pause
stop
end program main
9 11
module typedef
type student
integer(kind=4) Chinese,English,Math,Natural,Social
integer Total
end type
end module
program main
use typedef
implicit none
character(len=20)::filename="grades.bin"
integer,parameter::fileid=10
type(student)::students(20)
type(student)::mean
integer stat
integer i
open(fileid,file=filename,form="unformatted",status="old",access="direct",recl=5,iostat=stat ) !recl=1的意思是每个单元四个字节,因为fortran里单位为byte
if(stat/=0)then
write(*,*)"filename doesn't exist"
stop
end if
do i=1,20
read(fileid,rec=i,iostat=stat)students(i)%Chinese,students(i)%English,students(i)%Math,stude nts(i)%Natural,students(i)%Social
if(stat/=0)exit
students(i)%Total=students(i)%Chinese+students(i)%English+students(i)%Math+students(i)%Natur al+students(i)%Social
mean%Chinese=mean%Chinese+students(i)%Chinese
mean%English=mean%English+students(i)%English
mean%Math=mean%Math+students(i)%Math
mean%Natural=mean%Natural+students(i)%Natural
mean%Social=mean%Social+students(i)%Social
mean%Total=mean%Total+students(i)%Total
end do
write(*,"(7A7)")"序号","语文","数学","英语","自然","社会"
do i=1,20
write(*,"(7I7)")i,students(i)
end do
write(*,"(A7,6F7.1)")"平均分",real(mean%Chinese)/20.0,real(mean%Math)/20.0,&
real(mean%Chinese)/20.0,real(mean%Chinese)/20.0,&
real(mean%Chinese)/20.0,real(mean%Chinese)/20.0
pause
stop
end program main
程序9 12
program main
implicit none
character(len=20)::filename="encode2.txt"
integer,parameter::fileid=10
integer stat
character(len=79)::temp
integer::i,j
open(fileid,file=filename,status="old",iostat=stat)
if(stat/=0)then
write(*,*)"filename doesn't exist"
stop
end if
do while(.true.)
read(fileid,"(A79)",iostat=stat)temp
if(stat/=0)exit
j=0
do i=1,len_trim(temp)
if(ichar(temp(i:i))/=32)then
j=j+1 !加一个j做计数器,但其实encode2.txt中将空格也处理了,所以这里是错误的,好在encode2.txt中未出现空格,所以这个错误被掩盖了。但是要借鉴这个计数器的思想。 temp(i:i)=char(ichar(temp(i:i))-mod(j-1,3)-1) ! mod(j-1,3)-1 可以按照排列数字end if
end do
write(*,*)temp
end do
pause
stop
end program
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=)的语法格式声明字符变量的长度。
初中英语常见时态用法小结 一般现在时的用法 1) 经常性或习惯性的动作,常与表示频腮度的时间状语连用。 时间状语:every…, sometimes, at…, on Sunday I leave home for school at 7 every morning. 2) 客观真理,客观存在,科学事实。 The earth moves around the sun. Shanghai lies in the east of China. 3) 表示格言或警句中。 Pride goes before a fall. 骄者必败。 注意:此用法如果出现在宾语从句中,即使主句是过去时,从句谓语也要用一般现在时。 例:Columbus proved that the earth is round.. 4) 现在时刻的状态、能力、性格、个性。 I don’t want so much. Ann Wang writes good English but does not speak well. 比较:Now I put the sugar in the cup. I am doing my homework now. 第一句用一般现在时,用于操作演示或指导说明的示范性动作,表示言行的瞬间动作。再如:Now watch me, I switch on the current and stand back. 第二句中的now 是进行时的标志,表示正在进行的动作的客观状况,所以后句用一般现在时。 2. 一般过去时的用法 1)在确定的过去时间里所发生的动作或存在的状态。 时间状语有:yesterday, last week, an hour ago, the other day, in 1982等。 Where did you go just now? 2)表示在过去一段时间内,经常性或习惯性的动作。 When I was a child, I often played football in the street. Whenever the Browns went during their visit, they were given a warm welcome. 3)句型: It is time for sb. to do sth "到……时间了" "该……了" It is time sb. did sth. "时间已迟了" "早该……了" It is time for you to go to bed. 你该睡觉了。 It is time you went to bed. 你早该睡觉了。 would (had) rather sb. did sth. 表示’宁愿某人做某事’ I’d rather you came tomorrow. 4) wish, wonder, think, hope 等用过去时,作试探性的询问、请求、建议等。 I thought you might have some. 我以为你想要一些。 比较: 一般过去时表示的动作或状态都已成为过去,现已不复存在。 Christine was an invalid all her life. (含义:她已不在人间。) Christine has been an invalid all her life. (含义:她现在还活着)
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语句
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)