格式化:用来指定程序打印输出变量的具体形式,如位置、有效位数等。
READ(* , *)
和WRITE(* , *)
括号中第二个*
号均表示采用自由格式,此时输出中经常有多个额外的空格,且格式往往不统一。因此,可以采用格式化输出模式(采用格式描述符),来指定具体样式。
READ
和WRITE
一致)采用FORMAT
语句,并且结合语句标号(行号)来使用,如:
INTEGER:: a = 123
WRITE(*,100) a
100 FORMAT( ' ' , I5 ) ! 100是语句标号,将a变量用I5形式输出; ' '前面放置空格,实际上可以不要
直接在第二个*
号中指定具体样式,如:
INTEGER:: a = 123
WRITE(*,"(I5)") a ! 单引号也可以,如 WRITE(*,'(I5)')
符号 | 使用对象 |
---|---|
I |
整数 |
F |
实数 |
E |
实数,指数表示法(非标准科学计数法) |
ES |
实数,标准科学计数法 |
L |
逻辑数 |
X |
插入空格 |
T |
移动至同一数据行中某一字符位置 |
/ |
换行 |
符号 | 用途 |
---|---|
c |
一行中的第c 个字节位置 |
d |
用于实数,输入或输出的小数位数,不足则四舍五入 |
m |
至少输出的位数,若为2,则至少输出两位,即是变量的字符数小于2,也要输出两位 |
n |
插入空格的数目 |
r |
描述符的使用次数,如2I2 ,表示紧邻的两个变量用I2 格式输出,而不需要重复写两次 |
w |
域宽,输入或输出占用的字符数,可以理解成是放字符的有效空间 |
WRITE
使用对象I
)具体使用格式为:rIw
或 rIw.m
,具体用法见上述。
须注意:
*
号填充;I0
是特殊描述符,可以输出任意整数,而不需担心域宽不足。具体例子:
PROGRAM my_test
IMPLICIT NONE
INTEGER:: a = -123 , b , c = 5 , d = 12345
b = a+123
WRITE(*,100) a , b , c , d
WRITE(*,101) a , b , c , d
WRITE(*,200) a , b , c , d
WRITE(*,201) a , b , c , d
WRITE(*,300) a , b , c , d
WRITE(*,400) a , b , c , d
100 FORMAT( ' ' , I5 , I5 , I6 , I10)
101 FORMAT( ' ' , 2I5 , I6 , I10) ! 用了rIw中的r
200 FORMAT( ' ' , 2I5.0 , I6 , I10.6) ! 用了rIw.m中的r和m,m是至少显示的位数,这里是0,则输出必须要≥0位,由于b的数值为0,因此没有显示值
201 FORMAT( ' ' , 2I5.2 , I6 , I10.6) ! 输出必须≥1位,b要显示出“00”
300 FORMAT( ' ' , 2I5 , I6 , I3) ! d的数值有5位,但域宽只有3位,装不下,因此输出“ * ”作为警告s
400 FORMAT( ' ' , 4I0) ! 特殊零长度描述符,使整数完整显示出来,此时的域宽w就是整数的长度,总是能够容纳进去
STOP
END PROGRAM my_test
相应结果为:
-123 0 5 12345
-123 0 5 12345
-123 5 012345
-123 00 5 012345
-123 0 5***
-1230512345
F
)具体使用格式为:rFw.d
,具体用法见上述。
须注意:
*
号填充;空格
填充,小数部分在右侧用0
填充。具体例子:
PROGRAM my_test_F
IMPLICIT NONE
REAL:: a = -123. , b , c = 5.2456
b = a+123.
WRITE(*,100) a , b , c
WRITE(*,200) a , b , c
WRITE(*,300) a , b , c
WRITE(*,400) a , b , c
100 FORMAT( ' ' , F5.0 , F6.0 , F6.4) ! a、b变量,右对齐,左侧填空格;所有变量均使用了rFw.d中的d,即小数位数
200 FORMAT( ' ' , F5.0 , F6.0 , F6.3) ! c变量,由于只要求输出3位小数,因此四舍五入了
300 FORMAT( ' ' , F5.0 , 2F6.3) ! b变量,即使0没有小数,但也要补充完整;同时,使用了rFw.d中的r
400 FORMAT( ' ' , F5.0 , F6.3 , F3.2) ! c变量,由于需要输出2位小数,但域宽为3,而包含小数在内要4个字符宽(5.25),因此超出域宽,用*号填充
STOP
END PROGRAM my_test_F
相应结果为:
-123. 0.5.2456
-123. 0. 5.246
-123. 0.000 5.246
-123. 0.000***
E
)具体使用格式为:rEw.d
,具体用法见上述。
须注意:
w≥d+7
,如精确至2位小数则有±0.ddE±aa
,共9位字符;精确至5位小数则有±0.dddddE±aa
,共12位字符。±
和0
在某种情况下可以省略(见下述具体例子),因此该条件不是硬性条件,但由于能够满足所有情况且可视化效果较好,建议使用该条件;*
号填充。具体例子:
PROGRAM my_test_E
IMPLICIT NONE
REAL:: a = -123. , b , c = 52456.
b = a+123.
WRITE(*,100) a , b , c
WRITE(*,200) a , b , c
WRITE(*,300) a , b , c
100 FORMAT( ' ' , 2E9.2 , E11.4) ! rEw.d,最好要满足 w≥d+7,a,b变量是2位小数,c变量是4位
200 FORMAT( ' ' , E8.2 , E8.2 , E13.6) ! a变量, w<d+7,但是不影响,因为正负符号或者整数位上的0可以省略
300 FORMAT( ' ' , E7.2 , E7.2 , E13.6) ! 域宽条件:负数可以为w≥d+6,正数可以为w≥d+5(针对整数位为0),否则会用 * 号填充
STOP
END PROGRAM my_test_E
相应结果为:
-0.12E+03 0.00E+00 0.5246E+05
-.12E+030.00E+00 0.524560E+05
*******.00E+00 0.524560E+05
ES
)具体使用格式为:rESw.d
,具体用法见上述。
须注意:
E
相同,域宽满足一定条件:w≥d+7
,该条件同样不是十分严格,但是均能避免不利情况,因此建议使用该条件;*
号填充。具体例子:
PROGRAM my_test_ES
IMPLICIT NONE
REAL:: a = -123. , b , c = 52456.
b = a+123.
WRITE(*,100) a , b , c
WRITE(*,200) a , b , c
WRITE(*,300) a , b , c
100 FORMAT( ' ' , 2ES9.2 , ES11.4) ! rEw.d,最好要满足 w≥d+7,a,b变量是2位有效数字(小数),c变量是4位
200 FORMAT( ' ' , ES8.2 , ES8.2 , ES13.6) ! w<d+7,a变量,域宽已经受限,b变量不影响,因为开始的符号或者整数位上的0可以省略
300 FORMAT( ' ' , ES7.2 , ES7.2 , ES13.6) ! 如果负数必须为w≥d+7,正数可以为w≥d+6(对于整数位为0,则可以w≥d+5),否则会用 * 号填充
STOP
END PROGRAM my_test_ES
相应结果为:
-1.23E+02 0.00E+00 5.2456E+04
********0.00E+00 5.245600E+04
*******.00E+00 5.245600E+04
L
)具体使用格式为:rLw
,具体用法见上述。
须注意:
T
或F
;L0
会报错,因此总是可以输出结果。具体例子:
PROGRAM my_test_L
IMPLICIT NONE
LOGICAL:: a =.TRUE. , b = .FALSE.
WRITE(*,100) a , b
WRITE(*,200) a , b
100 FORMAT( ' ' , 2L5) ! 意义明确,不过过多解释
200 FORMAT( ' ' , 2L1)
STOP
END PROGRAM my_test_L
相应结果为:
T F
TF
A
)具体使用格式为:rA
或 rAw
,具体用法见上述。
须注意:
A0
会报错,因此总是可以输出结果。具体例子:
PROGRAM my_test_A
IMPLICIT NONE
CHARACTER(len=18):: a = "This is my_test_A."
WRITE(*,100) a
WRITE(*,200) a
WRITE(*,300) a
100 FORMAT( ' ' , A) ! 输出定义的字符串
200 FORMAT( ' ' , A25) ! 设置域宽为25,域宽大于定义长度,右对齐,左侧填充空格
300 FORMAT( ' ' , A6) ! 设置域宽为6,域宽小于定义长度,只显示局部相当于切片
STOP
END PROGRAM my_test_A
相应结果为:
This is my_test_A.
This is my_test_A.
This i
X
和T
)具体使用格式为:nX
和 Tc
,具体用法见上述。
须注意:
nX
表示在变量间插入n
个空格;Tc
表示将输出位置移动到本行中的第c
个字节。具体例子:
PROGRAM my_test_X_T
IMPLICIT NONE
INTEGER::a = 123 , b = 55
CHARACTER(len=5)::c = 'abcde'
CHARACTER(len=3)::d = 'KJH'
WRITE(*,100) a , b , c
WRITE(*,200) a
100 FORMAT( ' ' , T1 ,I3 , 1X , I2 , 1X , A5 , 1X , A3) ! 先跳到本行中第1个字符位置,然后逐一输出,每个变量用1个空格分隔
200 FORMAT( ' ' , T10 , I3) ! 先跳到本行中第10个字符位置,然后输出a变量
STOP
END PROGRAM my_test_X_T
相应结果为:
123 55 abcde
123
/
)换行符,使用:
/
表示多次换行。具体例子:
PROGRAM my_test_1
IMPLICIT NONE
INTEGER::a = 123 , b = 55
CHARACTER(len=5)::c = 'abcde'
WRITE(*,100) a , b , c
WRITE(*,200) a , b , c
WRITE(*,300) a , b , c
100 FORMAT( ' ' ,T1 , I3 , / , I2 ,/ , A5 ) ! 使用换行符,可以采用逗号
200 FORMAT( ' ' ,T1 , I3 / I2 / A5 ) ! 换行符不采用逗号也可以
300 FORMAT( ' ' ,T1 , I3 , /// , I2 ,// , A5 ) ! 有几个换行符,表示可以换行几次
STOP
END PROGRAM my_test_1
相应结果为:
123 ! 第一次输出结果
55
abcde
123 ! 第二次输出结果,与第一次结果一致
55
abcde
123 ! 第三次输出结果,多次换行
55
abcde
可以用括号,括号前输入重复次数,甚至可以嵌套,如下式:
FORMAT( ' ' , I5 , 3(I5 , I6)) ! 3是重复次数
FORMAT( ' ' , I5 , I5 , I6 , I5 , I6 , I5 , I6 ) ! 与上式等效
如果用*
号替代重复次数,则表示括号里的内容可以无限次重复使用,直至没有可输出的数据为止,如下所示:
FORMAT( ' ' , I5 , *(I5 , I6)) ! *是代表无限重复
对于WRITE
和FORMAT
语句,程序从变量列表和格式描述符列表的最左端开始,从左往右扫描并一 一对应,如果变量与格式描述符不是同样的类型和次序,则运行时会报错,如下例子;
INTEGER::a = 123 , b = 55
CHARACTER(len=5)::c = 'abcde'
WRITE(*,100) a , b , c
100 FORMAT( ' ' , I3 , I2 , I5 ) ! I5是整数类型的,c变量是字符串,会报错
注意,同时需要考虑格式重复的次数。
如果变量的个数大于格式描述符的个数,则可以重复调用,如下例所示:
PROGRAM my_test_2
IMPLICIT NONE
INTEGER::a = 123 , b = 55 , c = 32
WRITE(*,100) a , b , c
100 FORMAT(I5)
STOP
END PROGRAM my_test_2
相应结果为:
123
55
32
READ
使用对象I
)rIw
,具体用法见上述。F
、E
、ES
)rFw.d
,具体用法见上述。L
)rLw
,具体用法见上述。.TRUE.
和 .FALSE.
,或者以T
和F
开头的字符串。A
)rA
或 rAw
,具体用法见上述。WRITE
的方法相同。X
和T
)X
作用是跳过输入数据中不想读取的区域;T
作用是跳到某一位置。/
)常规用法是变量个数和格式描述符个数相同,扫描顺序、重复次数及括号的使用与WRITE
相一致。
当变量与格式描述符的个数不相一致时:
如果READ
语句在格式结束前用完了所有的变量(变量小于格式),则格式的使用就停在最后读取的变量后面,下一个READ
语句将从一个新的输入缓冲区开始,原来的输入缓冲区(即上一个READ
语句输入的数值)的数据将被丢弃,例子:
PROGRAM my_test_read
IMPLICIT NONE
INTEGER::i , j ,k , l , m
READ(*,100) i , j
READ(*,100) k , l , m
100 FORMAT( 5I2 )
WRITE (*,100) i , j ,k , l , m
STOP
END PROGRAM my_test_read
键盘输入为:
1,2,3,4,5
6,7,8,9,10
相应的结果为:
1 2 6 7 8
总结:变量用完了,格式描述符剩余,一个READ
对应一个输入缓冲区,如果要再次建立输入缓冲区,则要再使用READ
语句,新的READ
会重新读取新的输入缓冲区,而将上一次的输入缓冲区的数据丢弃。
如果READ
语句在使用完格式描述符后仍剩余变量(变量多于格式),则程序会自动丢弃当前的输入缓冲区,自动建立新的输入缓冲区(不需要READ
语句),并在格式中最右边不带重复次数的开始括号处重新开始,如下例子1:
PROGRAM my_test_read1
IMPLICIT NONE
INTEGER::i , j ,k , l , m
READ(*,100) i , j , k , l , m
100 FORMAT( T1, I2 , (T5 , 2I2) ) ! 第二次的输入缓冲区从右侧括号的T5开始
WRITE (*,100) i , j ,k , l , m
STOP
END PROGRAM my_test_read1
键盘输入为:
1,2,3,4,5
6,7,8,9,10
相应的结果为:
1 3 4
8 9
例子2:
PROGRAM my_test_read2
IMPLICIT NONE
INTEGER::i , j ,k , l , m
READ(*,200) i , j , k , l , m
200 FORMAT( T1, I2 , T5 , 2I2 ) ! 里面没有括号,从左往右依次读取
WRITE (*,200) i , j ,k , l , m
STOP
END PROGRAM my_test_read2
键盘输入为:
1,2,3,4,5
6,7,8,9,10
相应的结果为:
1 3 4
6 8