fortran心得

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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<ichar("0").or.code>ichar("9"))then
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
程序9 8
!现在有一个常出现的问题是:在定义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。

相关文档
最新文档