本章主要介绍了Fortran中如何进行格式化的输入输出,以及使用格式化控制的相关技巧。
参考书籍:彭国论.Fortran 95程序设计
文章目录
什么是格式化控制
通过format可以设置输出的格式,format在英文中也对应着“格式”的意思。
program test1
implicit none
integer a
a=10
write(*,*)a
write(*,100)a
100 format(I4) !fortran 77中 行代码号需要在前5个字符中,90则可以在任意位置
pause
end program test1
打印结果如下:
10
10
上述代码中:
write(*,*)
使用默认格式进行打印。write(*,100)
,使用行代码为100的命令来控制格式。100 format(I4)
其中,100为行代码号,I4
表示用4位数表示,位数不足将会以空格补齐。
格式控制描述
描述符 | 说明 |
---|---|
AW | 以w个字符宽输出字符串 |
BN | 定义文本框中的空位为NULL,输入时才需要使用 |
BZ | 定义文本框中的空位为0,输入时才使用 |
Dw.d | 以w个字符宽输出指数类型的浮点数,小数部分占d个字符 |
Ew.d[Ee] | 以w个字符宽输出指数类型的浮点数,小数部分占d个字符宽 |
ENw.d[Ee] | 以指数类型来输出浮点数 |
Fw.d | 以w个字符宽来输出浮点数,小数部分占d个字符宽 |
Gw.d[Ee] | 以w个字符宽来输出任何种类的数据 |
Iw[.m] | 以w个字符宽来输出整数,最少输出m个数字 |
Lw | 以w个字符宽来输出T或F |
nX | 把输出位置向右跳过n个位置 |
/ | 换行 |
: | 没有更多数据时结束输出 |
kP | k值控制输入输出的SCALE |
Tn | 输出的位置移动到本行第n列 |
TLn | 输出的位置向左相对移动n列 |
TRn | 输出的位置向右相对移动n列 |
SP | 在数值为正时加上“正号” |
SS | 取消SP |
Fortran 90添加格式 | |
Bw[.m] | 把整数转换成二进制来输出,输出会占w个字符宽,固定输出m个数字,m值可以不给定 |
Qw[.m] | 把整数转换成八进制来输出,输出会占w个字符宽,固定输出m个数字,m值可以不给定 |
Zw[.m] | 把整数转换成十六进制输出,输出会占w个字符宽,固定输出m个数字,m值可以不给定 |
利用上面的格式控制符,来进行一些简单的打印:
program test2
implicit none
integer a
real b
complex c
logical d
character(len=20) e
a=10
b=10.01
c=(10,5)
d=.true.
e="Hello World!"
write(*,"(2X,I2)")a
write(*,"(2X,F5.2)")b
write(*,"(2X,F4.1,F4.1)")c !复数用两个浮点数来控制
write(*,"(2X,L2)")d
write(*,"(2X, A15)")e
pause
end program test2
10
10.01
10.0 5.0
T
Hello World!
上面的写法是直接在write中直接加入代码控制。
将上述代码改为format格式::
program test2
implicit none
integer a
real b
complex c
logical d
character(len=20) e
a=10
b=10.01
c=(10,5)
d=.true.
e="Hello World!"
write(*,100)a
write(*,200)b
write(*,300)c !复数用两个浮点数来控制
write(*,400)d
write(*,500)e
100 format(2X,I2)
200 format(2X,F5.2)
300 format(2X,F4.1,F4.1)
400 format(2X,L2)
500 format(2X, A15)
pause
end program test2
不难看出,write和format各有优劣势:
优势 | 劣势 | |
---|---|---|
write | 减少程序行数,不需要找format,增加代码可读性 | 输出格式复杂时,编写较为麻烦,且不利于重复使用 |
format | 书写较为复杂的格式控制时更加清晰,可以重复使用 | 需要找到对应的行代码,不利于阅读 |
具体示例
上述格式控制中,
I
,F
,E
,A
,X
是最常用的几个格式,最好能熟记于心。
1)Iw[.m]
write(*,"(I5)") 100
:固定以5个字符输出数字100,前面两个空位会以空格补齐,结果如下:
100
如果所设置的文本框太小,足以打印全部数字, 例如:write(*,""(I3))10000
,输出结果如
***
显然,上述情况不会正常打印结果。
write(*,"(I5.4)") 100
:固定以5个字符打印,并且必须打印4个数字,效果如下:
0100
因为100不足四位,而又必须打印4个数字,因此会在前方进行补0。这种打印并不推荐,因为以通常默认八进制数是以0开头的。
2)Fw.d
write(*,"(F5.2)") 10.32
:以5个字符打印数字,其中小数部分保留2位。(注意:.
也算一位)
10.32
同理,超出文本框显示会打印*
。
3)Ew.d[Ee]和Dw.d[Ee]
write(*,"(E11.5)")100.01
:以科学计数法输出小数,总共打印11个字符,其中保留5位小数。
0.10001E+03
如果将上述代码中的11改为10,整数部分的0会被省略。
.10001E+03
write(*,"(E11.5E2)")
:以科学计数法输出小数,总共打印11个字符,其中保留5位小数,指数部分保留2位。
0.10001E+03
Dw.d[Ee]的方法与Ew.d[Ee],区别是科学计数法的字母是D
,而不是E
。
4)Aw
write(*,"(A15)")"Hello World!"
:以20个字符输出字符串Hello World!
,前方空余位置补空格。
Hello World!
当文本框不足以打印全部字符串时,会进行截取,例如将上述代码中的15改为10。
Hello Worl
5)nX
write(*,"20x,I3") 100
:先补20个空格,再以I3的格式打印整数100。
100
6)Lw
write(*,"(L5)") .true.
:打印,逻辑变量,并且前方预留4个空格。
T
7)Gw.d[Ee]
G可以输出所有类型的数据,固定使用w个字符来控制输出的宽度,d可以不使用,但定义时不能省略,必须随便赋一个数字。
- 当输入输出
字符
时,Gw.d会遵循Aw
的格式。 - 当输入输出
整数
时,Gw.d会遵循Iw
的格式。 - 当输入输出
逻辑数
时,Gw.d会遵循Lw
的格式。 - 当输入输出
浮点数时
时:当数值过大或过小时,Gw.d会遵循Ew.d
的格式;其他情况,Gw.d会遵循(Fa.b,4X)
的格式。
8)/
write(*,"(I4/I4)")100,200
:打印整数100,换行打印200
100
200
write(*,"('hello'//'world')")
:在write中直接打印字符时,字符串需要用单引号括起来,//
表示换两行
hello
world
9)Tc
write(*,"(T10,I4)") 100
:把输出位置移至本行的第10个字节
100
10)TLn和TRn
TLn:输出位置向左移动相对n个字节
TRn:输出位置向右移动相对n个字节
例如:
write(*,"(1X,'I',A5,TL5,A5)") "love","hate"
:
I hate you!
打印完love
后,TL5
向左移动5位,开始打印hate
,love
因此被覆盖了。
11)字符串
format中可以直接加入字符串,字符串需要用单引号括起来
write(*,100) 100
100 format('ANS:',I3)
ANS: 100
还可以使用wH的格式来控制输出的字符串,表示在此之后要输出w个字符串,例如:
write(*,100) 100
100 format(4HANS:,I3)
该方法打印效果同上,但不推荐使用。
12)SP和SS
SP用来显示正数的+
号,而SS则是用来取消SP的设置。
write(*,"(SP,I3,SS,I3)") 100,100
+100 100
如果要打印+
号,那么设置格式时需要多留一位。
13)BN和BZ
应用在输入数据时:BN定义没有输入的字节表示没有东西
;BZ定义没有数据的字节代表0
implicit none
integer a
read(*,"(BZ,I5)") a
print*,a
read(*,"(BN,I5)") a
print*,a
1 !输入1后输入4个空格,然后按回车
10000
1
1
BZ将空格处理解为0;而BN则认为没有东西。
14)kP
用于改变输入浮点数的Scale,输入的数值会自动乘上10的负k
次方。使用指数类型来输入时无效。
read (*,"(-2P,F3.1)") a
write(*,*) a
read (*,"(2P,F3.1)") a
write(*,*) a
打印结果如下:
1.5
150.000000
1.5
1.49999997E-02
15)Bw[.m]、Ow[.m]和Zw[.m]
Bw[.m]、Ow[.m]和Zw[.m]分别对应二进制、八进制和十六进制输出。打印占w个字符宽,固定输出m个数字,m值可以不给定。
write(*,"(B10.5)") 10
write(*,"(O10.5)") 10
write(*,"(Z10.5)") 10
01010
00012
0000A
格式化输出特殊技巧
1)格式重复输出
read a,b,c
a=1.0
b=2.0
c=3.0
write(*,"3(5X,F4.2,/)") a,b,c
1.00
2.00
3.00
3(5X,F4.2,/)
就等于将(5X,F4.2,/)
执行三次,更数学中的乘法有些类似。
2)将格式放入字符串变量中
character(len=10) strfmt
strfmt="(A15)"
write(*,strfmt) "Hello World!"
3)不同格式之间的逗号可以省略
例如用于控制整数和控制浮点数的格式之间可以省略逗号,但是一般建议加入逗号,方便代码的阅读。
write(*,"(I5F5.2A20)")100,5.2,"Hello World!"
IMPLICIT命令
Fortran中的变量不一定非要先声明才能使用,编译器会根据变量的第一个字母来定义变量的类型。例如:I、J、K、L、M、N字母开头的变量会被视为整数,其他字母开头的变量会被当成浮点数。
IMPLICIT命令可以用来设置“默认类型”,指定以某些字母开头的变量为何种类型。
implicit integer(a,b,c) !以a,b,c开头的变量为整型
implicit real(d-f) !以d,e,f开头的变量为浮点数
implicit complex(g-i,z) !以g,h,i,z开头的变量为复数
implicit none !关闭默认类型功能,所有变量均需要提前声明