Fortran 中write函数用法详解及格式化输出简介

发布时间 2023-11-23 17:12:27作者: yukina~

write 函数用法详解及格式化输出简介

write 的最基础用法

write(*,*) "String!" !最常见的写法
write(6,*) "String!" !严谨一些的写法
write(unit=6,fmt=*) "String!" !最严谨的写法

因为常见的写法实际上是简写,省略了 unit 和 fmt 两个描述,而屏幕输出 unit 位置就是 6。

另外 write(*,*)会使用默认格式来输出,不同编译器的默认格式可能会不一样。

print

print *,'hello'

print的用法和 write 大致是相同的,只是 print 后面不适用括号,且只有一个*,这个*用于限定输出格式,也就是说,print 相较于 write 缺少了指定输出位置的能力,只能针对屏幕来使用,日常编码过程中,我们应该尽量使用 write 来做输出的工作,因为如果日后想把程序的输出转换到其他地方,使用 wirte 命令的程序改写起来会比较容易。

格式化输出

format 命令可以用来设置输出格式。我们可以用两种方式给 write 添加格式:

write(*,100) a 
100 format(I4)
write(*,"(I4)") a
write(*,'(I4)') a

需要注意的是,若格式控制字符在 write 语句之内,则格式控制字符需要用引号括起来,单引号或双引号都可以。

这两种方式中,后者将 format 命令直接写进了 write 中,使用这种方法的好处是:

  1. 减少程序的行数
  2. 输出格式和 write 命令在同一行,可以使程序阅读起来比较清楚,不用再去寻找 format。
  3. 可以避免在程序代码中使用行号。

其缺点为:

  1. 输出格式很复杂时,编写起来会比较麻烦
  2. 在不同地方使用相同的输出格式时,程序代码会重复

注意

  1. 使用格式化输出时,需要注意“类型“的对应是否正确。类型对应错误时会出现很奇怪的输出结果,有时还会导致程序中断,所以要避免这种错误。

  2. 有些编译器会将输出的第一个字符拿来作为控制字符,不过这通常是应用在打印机输出时才需要使用。所以有些程序在输出时,会习惯在每一行的最前面预留一个空格(1X),现在比较新的编译器大都已经不在做这种处理。

  3. 设置输入输出格式时,不同的格式控制命令之间的逗号可以省略,但为了便于阅读一般将其保留

    write(*,"(1X,I5)") "hello",5
    write(*,"(1XI5)") "hello",5
    !二者所得的结果是一样的
    

常用格式控制符详解

格式化输出的控制字符非常丰富,但是常用的并不多,一般来说:“I,F,E,A,X“是最常用的几个格式,最好能把它们记下来。但这里会介绍所有的控制字符,包含常用的和非常用的。

格式控制符描述中的约定为:大写的是表示格式的字母,且最好在实际使用时也保持大写。小写的是需要用数字替换的用来指定长度的部分。

Iw.[m]

以 w 个字符的宽度来输出整数,且至少输出 m 个数字。

write(*,"(I5.3)") 10
>  010

输出了 5 个字符且强制输出了 3 个数字,数字不足时在左边补 0


注意 Fortran 会在设置的输出文本框不足时给出警告,如:

write(*,"(I3)") 10000
> *\** !\是转义字符,实际输出为三个星号

这是因为输出数字 10000 文本框的长度至少为 5 个字符字段,但输出格式只给了 3 个,因此输出星号作为警告


Fw.d

以 w 个字符文本框宽来输出浮点数,小数部分站 d 个字符宽

write(*,"(F9.3)") 123.45
>  123.450

左位补两个空白以填充至 9 个字符宽,右位补 0 以保证小数点后输出 3 位数字。

注意浮点数中小数点也需要占用一个字符位宽。

同样地,若输出文本框的设置不足时会出现星号警告。

Ew.d[Ee]

用科学计数法,以 w 个字符宽来输出浮点数,其中小数部分占 d 个字符宽,指数部分至少输出 e 个数字

write(*,"(E15.7)") 123.45 
>  0.1234500E+03

其中,左位补两个空白以满足 15 个字符位宽,小数点后数字补零以满足小数点后 7 位数字的要求。

write(*,"(E9.2E3)") 12.34
> 0.12E002

含空格共输出 9 个字符,其中有两位小数,指数部分输出三个数字

Dw.d

使用方法同 Ew.d,差别在于输出时用来代表指数的字母由 E 换成 D

write(*,"(D9.2)") 12.34
>  0.12D+02

使用 D 时无法指定指数部分数字位数

输出结果中的 D 和 E 始终是大写的

Aw

以 w 个字符位宽来输出字符串

write(*,"(A10)") "Hello"
>    Hello
write(*,"(A3)") "Hello"
>Hel

与数字不同,当字符串的输出文本框位宽不足时,不会输出星号警告,而是会直接将字符串截断,能输出几位就输出几位

nX

输出位置向右移动 x 位

write(*,"(5X,I3)") 100
>     100

先输出五个空白,再输出整数

Lw

以 w 个字符位宽来输出逻辑值

write(*,"(L4)") .true.
>   T

输出三个空白和一个 T

字符串

在格式化输出时可以在表示格式控制范围的括号内添加字符串,类似于 C 的 printf,当格式控制出现在单独一行时,我们可以用单引号或者双引号来表示字符串,但是若格式控制出现在 write 语句内,我们需要选择不同于括号外侧的引号来表示字符串。如:

write(*,'("hello")')
write(*,"('hello')")
write(*,100)
100 format("hello")
write(*,200)
200 format('hello')

以上四种写法的效果是一样的,最终都会输出 hello,但下面这样的写法是错误的,编译时会报错:

write(*,'('hello')')
write(*,"("hello")")

/

换行输出

write(*,"(I3//I3)") 10,10
> 10
>
>
> 10

两个数字输出之间存在两个空行

不常用格式控制符详解

Gw.d[Ee]

G可以用来输出所有类型的数据,固定使用 w 个字符位宽来输出,d 不一定会使用,但不能省略。

用来输入/输出字符时,Gw.d=Aw,d 必须随便给一个数字,不能省略。

用来输入/输出整数时,Gw.d=Iw,d 必须随便给一个数字,不能省略。

用来输入/输出逻辑数时,Gw.d=Lw,d 必须随便给一个数字,不能省略。

输出浮点数时比较复杂的情况。Gw.d有时候会相等于 Fw.d,有时会相等于 Ew.d。

Tc

把输出的位置移动到本行的第 c 个字符处

write(*,"(T3,I3)") 100
>  100 !前面存在两个空格,从第三个字符处开始打印
write(*,"(10X,T3,I3)") 100
>  100  !nvfortran 编译器
>          100 !gfortran编译器
write(*,"('hello',T2,I2) 10
>h10lo !nvfortran编译器
>h10lo !gfortran编译器

TLn

输出位置向左相对移动 n 个字符。如:

write(*,"(1x,A10,TL3,I3)") 'call 119',100
> call 110

TRn

输出位置相对向右移动 n 个字符。

SP,SS

加了 SP 后,在输出数字时,如果数值为正则加上“正号“,SS 则用来取消 SP 的功能。如:

write(*,"(SP,I2,1X,I2,1X,SS,I1)") 5,5,5
>+5 +5 5

需要注意的是正号也需要占用一个字符位宽,若给定的位宽不够,则会出现星号警告,如:

write(*,"(SP,I1,1X,I1,1X,SS,I1)") 5,5,5
>* * 5

BN,BZ

这两个格式控制符实际上不会用在 write 语句中,仅出现在 read 语句里,但在这里也简要进行说明。

这两个格式控制符应用在输入中,BN 表示在读取输入时,将没有数据的字节看做空白,BZ 则表示在读取输入时将没有数据的字节看做 0。如:

read(*,"(BZ,I5)") A 
!从键盘或文件输入 1,A 的值会被赋为 10000
read(*,"(BZ,I5)") A 
!从键盘或文件输入 1,A 的值会被赋为 1

通常应用在从文件读取数据时,从键盘读取数据时不太会去使用这个功能。

kP

同样是用于输入的格式控制符,用来改变输入浮点数的 scale。输入的数值会自动乘上 10-k注意是-k 次方。不过如果使用指数类型来输入时就会无效。

read(*,"(-3P,F5.2)") A 
!输入 1.0 时,A=1000,因为会自动乘以 10^3

Bw[.m]

把整数转换成二进制来输出,输出会占 w 个字符宽,固定输出 m 个数字,m 的值可以不给定。

write(*,"(B6.5)") 3
> 00011

Ow[.m]

把整数转换成八进制来输出,会占 w 个字符位宽,输出 m 个数字。m 的值可以不给定。

write(*,"(O6.5)") 3
> 00003

Zw[.m]

把整数转换成十六进制来输出,会占 w 个字符位宽,输出 m 个数字。m 的值可以不给定。

write(*,"(Z2)") 20
>14

使用 print 进行格式化输出

print 的使用方法和 write 非常类似,只是不能指定输出位置,在 print 中指定输出格式的方法如下:

print 100,a !使用行代码 100 的 format 来输出
print "(A10)","Hello" !直接把格式字符串写在 print 中

附录

format 命令格式控制符号表

format 命令中可以使用很多的格式控制进行描述,下面是列出所有格式命令的表格,方括号内的东西可以省略。

image-20231123101440949

下面是 Fortran 90 添加的格式:

image-20231123101602308

参考

《Fortran95 程序设计》彭国伦版 第四章 输入输出及声明