READ(,)和WRITE(,)中,两个的意义:
第一个:该处的数据域指明从哪个输入/输出单元(I/O单元)读入/输出数据;
第二个:该处的数据域指明读入数据的格式。
*Fortran控制字符
控制字符 | 作用 |
---|---|
1 | 跳到新页 |
空格 | 单行间距 |
0 | 双行间距 |
+ | 没有行距(在前一行上打印) |
我在Windows平台IVF+VS中写的以下代码,与书中描写的结果并不一致,这些控制字符没有起到作用,而是直接被输出出来了。
PROGRAM main
IMPLICIT NONE
WRITE(*,100)
100 FORMAT('1','This heading is at the top of a new page.')
WRITE(*,200)
200 FORMAT('0','Control Character Action ')
WRITE(*,300)
300 FORMAT(' ','================= ======')
END PROGRAM
实际运行结果如下:
1This heading is at the top of a new page. 0Control Character Action ================= ====== 请按任意键继续. . .
而不是行间距的变化,这些描述行间距的控制字符被直接输出出来了。
格式描述符
格式描述符的四个基本类别:
- 描述文本行垂直位置的格式描述符;
- 描述行中数据水平位置的格式描述符;
- 描述特定数值的输出格式的格式描述符;
- 控制格式中一部分的重复的格式描述符。
格式描述符使用的符号
符号 | 含义 |
---|---|
c | 列号 |
d | 实数输入或输出的小数位右边的位数 |
m | 要显示的最小位数 |
n | 要跳过的空格数 |
r | 重复计数,一个或一组描述符的使用次数 |
w | 域宽,输入或输出占用的字符数 |
整数输出-I描述符
格式:r_I_w或r_I_w.m
例:
PROGRAM main
IMPLICIT NONE
INTEGER::index = -12, junk = 4, number = -12345
WRITE(*,110) index, index+12, junk, number
WRITE(*,120) index, index+12, junk, number
WRITE(*,130) index, index+12, junk, number
110 FORMAT(' ', 2I5, I6, I10)
120 FORMAT(' ', 2I5.0, I6, I10.8)
130 FORMAT(' ', 2I5.3, I6, I5)
END PROGRAM
结果如下:
整数数值在给定的显示域宽内右对齐打印。
注:输出结果中的,是因为本身整数过大,而给的输出域宽太窄,不足以放入打印区域,那么就用表示。
特殊的零长度描述符,I0,可以使整数输出到足够容纳其信息的可变域宽中。
实数输出-F描述符
格式:r_F_w.d
例:
PROGRAM main
IMPLICIT NONE
REAL::a = -12.3, b = .123, c = 123.456
WRITE(*,110) a, b, c
WRITE(*,120) a, b, c
110 FORMAT(2F6.3, F8.3)
120 FORMAT(3F10.2)
END PROGRAM
结果如下:
实数数值在给定的显示域宽内右对齐打印。
如果有必要,数值在显示前会自己四舍五入。
如果要求显示的小数点后位数多余实际,会自己添加额外的0。
给定的域宽太窄,会显示星号。
实数输出-E描述符
格式:r_E_w.d
E描述符使数据规范到0.1到1.0之间的数乘10的幂。
使用E格式,要特别注意区域大小,一般来说,E格式描述符域宽应满足以下表达式:
w≥d+7
例:
PROGRAM main
IMPLICIT NONE
REAL::a = 1.2346E6, b = 0.001, c = -77.7E10, d = -77.7E10
WRITE(*,110) a, b, c, d
110 FORMAT(2E14.4, E13.6, E11.6)
END PROGRAM
真正的科学记数法-ES描述符
格式:r_ES_w.d
ES格式描述符域宽应满足以下表达式:
w≥d+7
例:
PROGRAM main
IMPLICIT NONE
REAL::a = 1.2346E6, b = 0.001, c = -77.7E10
WRITE(*,110) a, b, c
110 FORMAT(2ES14.4, ES12.6)
END PROGRAM
逻辑输出-L描述符
格式:r_L_w
例:
PROGRAM main
IMPLICIT NONE
LOGICAL::output = .TRUE., debug = .FALSE.
WRITE(*,110) output, debug
110 FORMAT(2L5)
END PROGRAM
字符输出-A描述符
格式:r_A或_r_A_w
r_A:在宽度与要显示的字符数相同的区域内显示字符数据 _r_A_w:在一个固定宽度w的区域内显示字符数据
例:
PROGRAM main
IMPLICIT NONE
CHARACTER(len=17)::string = 'This is a string.'
WRITE(*,10) string
WRITE(*,11) string
WRITE(*,12) string
10 FORMAT(A)
11 FORMAT(A20)
12 FORMAT(A6)
END PROGRAM
水平定位-X和T描述符
X描述符:格式nX
n为插入的空格数,用于在输出行上的两个数值之间添加一个或多个空格
T描述符:格式Tc
c为要转到的列号,用来输出缓冲区中直接跳到一个特定列
例:
PROGRAM main
IMPLICIT NONE
CHARACTER(len=10)::first_name='James'
CHARACTER::initial='R'
CHARACTER(len=16)::last_name='Johnson'
CHARACTER(len=9)::class='COSC 2301'
INTEGER::grade=92
WRITE(*,100)first_name,initial,last_name,grade,class
100 FORMAT(A10,1X,A1,1X,A10,4X,I3,T51,A9)
END PROGRAM
改变输出行-斜线(/)描述符
斜线(/)描述符可以在一个WRITE语句中将输出行打印在多行上。
要跳过几行就加几个斜线(/),例如,一条(/)会在第二行继续打印;两条(/)会在第三行(跳过一行)继续打印……
例:
PROGRAM main
IMPLICIT NONE
INTEGER::index=10
REAL::time=300.,depth=330.,amplitude=850.65,phase=30.
WRITE(*,100)index, time, depth, amplitude, phase
100 FORMAT(T20,'Results for Test Number ',I3,///,&
'Time = ',F7.0,/,&
'Depth = ',F7.1,'meters',/,&
'Amplitude = ',F8.2,/,&
'Phase = ',F7.1)
END PROGRAM
例题
PROGRAM table
IMPLICIT NONE
INTEGER::i
INTEGER::square
INTEGER::cube
REAL::square_root
WRITE(*,100)
100 FORMAT(T3,'Table of Square Roots, Squares, and Cubes'/)
WRITE(*,110)
110 Format(T4,'Number',T13,'Square Root',T29,'Square',T39,'Cube')
WRITE(*,120)
120 FORMAT(T4,'======',T13,'===========',T29,'======',T39,'===='/)
DO i = 1,10
square_root = SQRT(REAL(i))
square = i**2
cube = i**3
WRITE(*,130)i,square_root,square,cube
130 FORMAT(1X,T4,I4,T13,F10.6,T27,I6,T37,I6)
END DO
END PROGRAM
文件及文件处理介绍
OPEN语句
格式:OPEN (open_list)
open_list为一组子句,最重要的6项:
- UNIT=指明与文件关联的i/o单元号,格式:
UNIT=int_expr
,int_expr为非负整数;- FILE=指定要打开的文件名,格式:
FILE=char_expr
,char_expr是包含要打开文件名的字符值;- STATUS=指定要打开文件的状态,格式:
STATUS=char_expr
,char_expr为:”OLD”,”NEW”(打开新文件,如若存在,IOSTAT的变量会返回错误值),”REPLACE”(无论是否有同名文件,都打开一个新文件,若文件已存在,则删除,再建立新文件),”SCRATCH”(临时文件,保存程序运行中间结果,当文件被关闭或程序运行结束,该文件会被删除),”UNKNOW”;- ACTION=指定文件是否以只读、只写或读写方式打开,格式:
ACTION=char_expr
,char_expr为:”READ”,”WRITE”,”READWRITE”,若未指定,则以读写方式打开;- IOSTAT=指定一个整数变量名,打开状态返回到这个变量中,格式:
IOSTAT=int_var
,其中int_var为整数变量。如果打开成功,返回给这个整数变量的值为0,若不成功,返回正整数值。- IOMSG=指定一个字符变量名,如果发生错误,将包含错误信息,格式:
IOMSG=chart_var
。如果OPEN执行成功,字符变量内容不变,如果不成功,错误信息返回到该字符串。
CLOSE语句
格式:CLOSE (close_list)
close_list必须包含一个指定i/o单元号子句,也可指定其他选项(第14章)。
无CLOSE语句,程序运行结束也会自动关闭。
非临时文件关闭后,可再次OPEN打开,可以使用新的i/o单元号,也可使用之前的。
文件关闭后,i/o单元会被释放,可以在新的OPEN语句中再次使用该i/o单元号。
READ语句的IOSTAT=和IOMSG=子句
当使用磁盘文件,可以给READ语句增加IOSTAT=和IOMSG=子句。
IOSTAT=子句格式:IOSTAT=int_var
若READ成功执行,给整型变量int_var返回0; 若由于文件或格式错误,返回与系统错误信息对应的整数; 若由于已经到达输入数据文件尾部而导致语句执行失败,返回一个负数。
READ语句包含IOMSG=子句,在返回的i/o状态为非零值时,IOMSG=子句返回的字符串将以语句的形式解释发生的错误。
例:
PROGRAM read_file
IMPLICIT NONE
CHARACTER(LEN=20)::filename !要打开的文件名
CHARACTER(LEN=80)::msg !错误信息
INTEGER::nvals=0 !读入数值的个数
INTEGER::status !I/O状态
REAL::value !读入的实数值
WRITE(*,*) 'Please enter input file name:'
READ(*,*) filename
WRITE(*,100) filename
100 FORMAT('The input file name is ', A)
OPEN(UNIT=3,FILE=filename,STATUS='OLD',ACTION='READ',&
IOSTAT=status,IOMSG=msg)
openif:IF(status == 0) THEN
readloop:DO
READ(3,*,IOSTAT=status) value
IF(status /= 0) EXIT
nvals = nvals + 1
WRITE(*,101) nvals, value
101 FORMAT('Line ',I6,':Value = ',F10.4)
END DO readloop
readif:IF(status > 0) THEN
WRITE(*,102) nvals+1
102 FORMAT('An error occurred reading line ',I6)
ELSE
WRITE(*,103) nvals
103 FORMAT('End of file reached. There are ',I6,&
' values in the file.')
END IF readif
ELSE openif
WRITE(*,104) status
104 FORMAT('Error opening file: IOSTAT = ',I6)
WRITE(*,105) TRIM(msg)
105 FORMAT(A)
END IF openif
CLOSE(UNIT=3)
END PROGRAM read_file
文件定位
BACKSPACE语句:BACKSPACE(UNIT=unit)
,每次调用它都可以回退一条记录;
REWIND语句:REWIND(UNIT=unit)
,可以从文件头重新开始文件。
两条语句也可使用IOSTAT=和IOMSG=子句,以检测回退或倒回操作期间是否发生错误。
例:
PROGRAM least_squares_fit
IMPLICIT NONE
INTEGER,PARAMETER::LU = 18
CHARACTER(LEN=24)::filename
INTEGER::ierror
CHARACTER(LEN=80)::msg
INTEGER::n = 0
REAL::k
REAL::sum_x = 0.
REAL::sum_x2 = 0.
REAL::sum_xy = 0.
REAL::sum_y = 0.
REAL::x
REAL::x_bar
REAL::y
REAL::y_bar
REAL::b
WRITE(*,100)
100 FORMAT('该程序功能为根据输入的数据拟合出最佳平方逼近的直线。',/,&
'直线形式为:y = k*x + b',/,'请输入包含(x,y)数据的文件名:')
READ(*,'(A)') filename
OPEN(UNIT=LU,FILE=filename,STATUS='OLD',IOSTAT=ierror,IOMSG=msg)
errorcheck:IF(ierror > 0) THEN
WRITE(*,1010) filename
1010 FORMAT('错误:文件:',A,'不存在!')
WRITE(*,'(A)') TRIM(msg)
ELSE
DO
READ(LU,*,IOSTAT=ierror) x,y
IF(ierror /= 0) EXIT
n = n + 1
sum_x = sum_x + x
sum_y = sum_y + y
sum_x2 = sum_x2 + x**2
sum_xy = sum_xy + x*y
END DO
x_bar = sum_x / REAL(n)
y_bar = sum_y / REAL(n)
k = (sum_xy - sum_x*y_bar) / (sum_x2 - sum_x*x_bar)
b = y_bar - k*x_bar
WRITE(*,1020) k,b,n
1020 FORMAT('斜率(k) = ',F12.3,/,&
'截距(b) = ',F12.3,/,&
'输入的(x,y)对数为',I12,'对')
CLOSE(UNIT=LU)
END IF errorcheck
END PROGRAM least_squares_fit