READ(,)和WRITE(,)中,两个的意义:
第一个:该处的数据域指明从哪个输入/输出单元(I/O单元)读入/输出数据;
第二个:该处的数据域指明读入数据的格式。
*Fortran控制字符
| 控制字符 | 作用 |
|---|---|
| 1 | 跳到新页 |
| 空格 | 单行间距 |
| 0 | 双行间距 |
| + | 没有行距(在前一行上打印) |
我在Windows平台IVF+VS中写的以下代码,与书中描写的结果并不一致,这些控制字符没有起到作用,而是直接被输出出来了。
PROGRAM mainIMPLICIT NONEWRITE(*,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 mainIMPLICIT NONEINTEGER::index = -12, junk = 4, number = -12345WRITE(*,110) index, index+12, junk, numberWRITE(*,120) index, index+12, junk, numberWRITE(*,130) index, index+12, junk, number110 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 mainIMPLICIT NONEREAL::a = -12.3, b = .123, c = 123.456WRITE(*,110) a, b, cWRITE(*,120) a, b, c110 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 mainIMPLICIT NONEREAL::a = 1.2346E6, b = 0.001, c = -77.7E10, d = -77.7E10WRITE(*,110) a, b, c, d110 FORMAT(2E14.4, E13.6, E11.6)END PROGRAM
真正的科学记数法-ES描述符
格式:r_ES_w.d
ES格式描述符域宽应满足以下表达式:
w≥d+7
例:
PROGRAM mainIMPLICIT NONEREAL::a = 1.2346E6, b = 0.001, c = -77.7E10WRITE(*,110) a, b, c110 FORMAT(2ES14.4, ES12.6)END PROGRAM
逻辑输出-L描述符
格式:r_L_w
例:
PROGRAM mainIMPLICIT NONELOGICAL::output = .TRUE., debug = .FALSE.WRITE(*,110) output, debug110 FORMAT(2L5)END PROGRAM
字符输出-A描述符
格式:r_A或_r_A_w
r_A:在宽度与要显示的字符数相同的区域内显示字符数据 _r_A_w:在一个固定宽度w的区域内显示字符数据
例:
PROGRAM mainIMPLICIT NONECHARACTER(len=17)::string = 'This is a string.'WRITE(*,10) stringWRITE(*,11) stringWRITE(*,12) string10 FORMAT(A)11 FORMAT(A20)12 FORMAT(A6)END PROGRAM
水平定位-X和T描述符
X描述符:格式nX
n为插入的空格数,用于在输出行上的两个数值之间添加一个或多个空格
T描述符:格式Tc
c为要转到的列号,用来输出缓冲区中直接跳到一个特定列
例:
PROGRAM mainIMPLICIT NONECHARACTER(len=10)::first_name='James'CHARACTER::initial='R'CHARACTER(len=16)::last_name='Johnson'CHARACTER(len=9)::class='COSC 2301'INTEGER::grade=92WRITE(*,100)first_name,initial,last_name,grade,class100 FORMAT(A10,1X,A1,1X,A10,4X,I3,T51,A9)END PROGRAM
改变输出行-斜线(/)描述符
斜线(/)描述符可以在一个WRITE语句中将输出行打印在多行上。
要跳过几行就加几个斜线(/),例如,一条(/)会在第二行继续打印;两条(/)会在第三行(跳过一行)继续打印……
例:
PROGRAM mainIMPLICIT NONEINTEGER::index=10REAL::time=300.,depth=330.,amplitude=850.65,phase=30.WRITE(*,100)index, time, depth, amplitude, phase100 FORMAT(T20,'Results for Test Number ',I3,///,&'Time = ',F7.0,/,&'Depth = ',F7.1,'meters',/,&'Amplitude = ',F8.2,/,&'Phase = ',F7.1)END PROGRAM
例题
PROGRAM tableIMPLICIT NONEINTEGER::iINTEGER::squareINTEGER::cubeREAL::square_rootWRITE(*,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,10square_root = SQRT(REAL(i))square = i**2cube = i**3WRITE(*,130)i,square_root,square,cube130 FORMAT(1X,T4,I4,T13,F10.6,T27,I6,T37,I6)END DOEND 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_fileIMPLICIT NONECHARACTER(LEN=20)::filename !要打开的文件名CHARACTER(LEN=80)::msg !错误信息INTEGER::nvals=0 !读入数值的个数INTEGER::status !I/O状态REAL::value !读入的实数值WRITE(*,*) 'Please enter input file name:'READ(*,*) filenameWRITE(*,100) filename100 FORMAT('The input file name is ', A)OPEN(UNIT=3,FILE=filename,STATUS='OLD',ACTION='READ',&IOSTAT=status,IOMSG=msg)openif:IF(status == 0) THENreadloop:DOREAD(3,*,IOSTAT=status) valueIF(status /= 0) EXITnvals = nvals + 1WRITE(*,101) nvals, value101 FORMAT('Line ',I6,':Value = ',F10.4)END DO readloopreadif:IF(status > 0) THENWRITE(*,102) nvals+1102 FORMAT('An error occurred reading line ',I6)ELSEWRITE(*,103) nvals103 FORMAT('End of file reached. There are ',I6,&' values in the file.')END IF readifELSE openifWRITE(*,104) status104 FORMAT('Error opening file: IOSTAT = ',I6)WRITE(*,105) TRIM(msg)105 FORMAT(A)END IF openifCLOSE(UNIT=3)END PROGRAM read_file
文件定位
BACKSPACE语句:BACKSPACE(UNIT=unit),每次调用它都可以回退一条记录;
REWIND语句:REWIND(UNIT=unit),可以从文件头重新开始文件。
两条语句也可使用IOSTAT=和IOMSG=子句,以检测回退或倒回操作期间是否发生错误。
例:
PROGRAM least_squares_fitIMPLICIT NONEINTEGER,PARAMETER::LU = 18CHARACTER(LEN=24)::filenameINTEGER::ierrorCHARACTER(LEN=80)::msgINTEGER::n = 0REAL::kREAL::sum_x = 0.REAL::sum_x2 = 0.REAL::sum_xy = 0.REAL::sum_y = 0.REAL::xREAL::x_barREAL::yREAL::y_barREAL::bWRITE(*,100)100 FORMAT('该程序功能为根据输入的数据拟合出最佳平方逼近的直线。',/,&'直线形式为:y = k*x + b',/,'请输入包含(x,y)数据的文件名:')READ(*,'(A)') filenameOPEN(UNIT=LU,FILE=filename,STATUS='OLD',IOSTAT=ierror,IOMSG=msg)errorcheck:IF(ierror > 0) THENWRITE(*,1010) filename1010 FORMAT('错误:文件:',A,'不存在!')WRITE(*,'(A)') TRIM(msg)ELSEDOREAD(LU,*,IOSTAT=ierror) x,yIF(ierror /= 0) EXITn = n + 1sum_x = sum_x + xsum_y = sum_y + ysum_x2 = sum_x2 + x**2sum_xy = sum_xy + x*yEND DOx_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_barWRITE(*,1020) k,b,n1020 FORMAT('斜率(k) = ',F12.3,/,&'截距(b) = ',F12.3,/,&'输入的(x,y)对数为',I12,'对')CLOSE(UNIT=LU)END IF errorcheckEND PROGRAM least_squares_fit


