360 likes | 503 Views
第 11 章 高级输出与输入. 在第 3 章中,介绍了简单的输入输出操作(也称为表控输入输出、直接列表输入输出)语句 READ 、 WRITE 和 PRINT 。这些输入输出操作语句简单易学、使用方便。但是如果想要使输入输出的数据更为美观、易读易用或是想要实现一些特殊的效果,这些简单输入输出语句就显得力不从心了。在本章中,将介绍同高级输入输出相关的语句设置、不同种类的格式编辑符等内容。通过本章的介绍,就可以使程序在输入输出这方面显得更加专业。. 11.1 输入输出语句的格式化设置.
E N D
第11章 高级输出与输入 • 在第3章中,介绍了简单的输入输出操作(也称为表控输入输出、直接列表输入输出)语句READ、WRITE和PRINT。这些输入输出操作语句简单易学、使用方便。但是如果想要使输入输出的数据更为美观、易读易用或是想要实现一些特殊的效果,这些简单输入输出语句就显得力不从心了。在本章中,将介绍同高级输入输出相关的语句设置、不同种类的格式编辑符等内容。通过本章的介绍,就可以使程序在输入输出这方面显得更加专业。
11.1 输入输出语句的格式化设置 • 在第3章中,提到过简单输入输出语句同高级输入输出语句在形式上没有太大差别。高级输入输出语句之所以高级,主要因为其在于句说明中添加了丰富的格式控制说明项。正是这些格式控制说明项使输入输出语句在进行数据的输入输出操作时显得丰富多彩。本节将介绍同输入输出语句相关的一些详细设置。 • 在第3章中,已经介绍了三种常用的简单输入输出语句:WRITE语句、PRINT语句和READ语句。实际上高级输入输出语句也是这三个语句。只是在使用高级输入输出操作时,需要设置更多的输入输出控制选项。而简单输入输出语句无需设置这些控制选项,只要用星号“*”就可以表示系统默认的输入输出操作方式了。 • 要在输入输出语句中使用高级的输入输出选项,就要使用专门的语句来定义格式的形式。这个语句就是FORMAT语句,也称为格式说明语句。该语句的语法形式为: • FORMAT (format-list)
11.2 输入输出语句与格式语句 • 在前一小节中,详细介绍了FORMAY语句的相关知识。在介绍的过程中,提到了FORMAT语句必须是有标号的,以便在输入输出语句中进行引用。在这一节中,就要介绍在输入输出语句中如何引用FORMAT语句。当FORMAT语句定义完全并编上标号后,就可以在输入输出语句中通过引用标号的形式来引用格式说明语句。三种输入输出语句引用格式说明语句的形式罗列如下所述。
11.2.1 WRITE语句引用格式说明语句 • 在向外部设备输出时,语法形式如下: • WRITE(设备号, [FMT=]格式说明语句标号) [变量列表] • 语句中,设备号表示要在其上输出数据的设备,当设备号为星号“*”时,表示向默认的设备输出;关键字段“FMT=”用来显示说明其后所跟的标号为格式说明语句的标号,当WRITE语句说明项中只含有一项时,“FMT=”可以省略;语句中允许变量列表为空,此时WRITE语句的作用是输出一个空白行。
11.2.2 PRINT语句引用格式说明语句 • PRINT语句只能向计算机的默认设备(即屏幕)上输出数据。因此PRINT语句引用格式说明语句的形式中不含有设备号这样的参数。语句的语法形式如下: • PRINT 格式说明语句标号[, 变量列表] • 需要注意的是,PRINT语句中在引用格式说明语句标号时,不允许使用关键字段“FMT=”。这和WRITE语句有一个重要的区别。语句中允许变量列表为空,作用与WRITE语句相同。
11.2.3 READ语句引用格式说明语句 • 在从外部设备中输入时,语法形式如下: • READ(设备号, [FMT=]格式说明语句标号) [变量列表] • 语句中,设备号表示要在其上输入数据的设备,当设备号为星号“*”时,表示从默认的设备(一般是键盘)输入;关键字段“FMT=”用来显示说明其后所跟的标号为格式说明语句的标号,当WRITE语句说明项中只含有一项时,“FMT=”可以省略;语句中允许变量列表为空,此时READ语句将等待输入,指导用户键入回车键。
11.2.4 第一个输入输出综合应用 • 下面来看一段代码,这段代码综合应用了上述三种输入输出语句和FORMAT语句的交互作用。 • TEST1101.F90 • ! WRITE & FORMAT 语句的范例 • PROGRAM TEST1101 • IMPLICIT NONE • ! 变量定义 • INTEGER :: I, J, K • REAL :: A, B, C • ! 可执行段 • WRITE(*, *)'Input:' • READ (*, 100)I, J, K • READ(*, 200)A, B, C • WRITE(*, *)'Output:' • WRITE(*, 300) I, J, K • PRINT 400, A, B, C • ! 格式说明 • 100 FORMAT(1X, 3(I3, 1X)) • 200 FORMAT(1X, 3(F6.2, 1X)) • 300 FORMAT(1X, 'I=', I3, 'J=', I3, 'K=', I3) • 400 FORMAT(1X, 'A=', F6.2, 'B=', F6.2, 'C=', F6.2) • END PROGRAM TEST1101
11.3 格式编辑符概述 • 用户在指定输出格式时,需要特定的方式向系统说明格式的“相貌”。在Fortran中,描述格式“相貌”的工作由“格式编辑符”(或“编辑描述符”)来完成。格式编辑符的作用就是将数据进行类似书报编辑对文字进行编辑排版一样的处理,使数据以更美观的形式进行显示。在Fortran中,格式编辑符按照用途可以分为数据格式编辑符、控制格式编辑符和字符串格式编辑符三大类。下面将对这三类编辑符的使用和功能进行讲解。
11.4 数据格式编辑符 • 顾名思义,数据格式编辑符主要针对程序中的整型、实型、复型、逻辑型和字符型数据的输入输出格式控制。下面将对其中最常用的几种编辑符的作用和用法进行讲解。
11.4.1 I编辑符 • I编辑符适用于整型数据的输入输出,其一般形式为: • Iw[.m] • I是英文单词“Integer”的第一个字母,表示“整型数编辑符”。 • w用来指示以w个字符的宽度来输出数据(通常称一个数据所占的宽度为“字段宽度”),负数的符号也包含在字段宽度内。如果要输出的数据实际宽度超出了w规定的宽度,则不输出有效数据,而在该字段宽度范围内用星号“*”填充。 • m用来指示至少需要输出m个字符宽度的数字。如果输出数据的实际宽度小于m,则会在数据前面不足部分用0填充;如果输出数据的实际宽度超过m,则按输出数据的实际宽度进行输出(但不能超过w)。
11.4.2 F编辑符 • F编辑符适用于实数的小数形式输出,其一般形式为: • Fw.d • F是英文单词“Fixed point number”的首字母,表示“浮点数编辑符”。 • w仍然表示要输出的“字段宽度”,包含一个小数点和负数的负号。如果要输出的数据实际宽度超出了w规定的宽度,则不输出有效数据,而在该字段宽度范围内用星号“*”填充。 • d表示要输出数据的小数位数。如果要输出的实际数据的小数位数小于d,则会在小数后不足的部分补充0;如果要输出的实际数据的小数位数大于d,则会将实际数据中多余的小数部分按四舍五入规则去掉。
11.4.3 E编辑符 • E编辑符用于输出指数形式的实数,其一般形式为: • Ew.d[Ee] • E是英文单词“Exponent”的首字母,表示“指数编辑符”。 • w还是表示要输出的“字段宽度”,包含指数部分所占的4个字符的宽度和负数的负号。如果要输出的数据实际宽度超出了w规定的宽度,则在该字段宽度范围内用星号“*”填充;如果输出的数据实际宽度小于w规定的宽度,则在输出数据的前面用空格填充。 • d表示要输出数据的小数位数。小数部分的位数可以由公式w≥d+7来确定,公式中的“7”表示一个小数点、小数点前的0、一个负号和指数部分所占的4位。如果实际数据在指数形式下的小数位数大于d,则多出的小数部分按四舍五入规则进行舍入;如果实际数在指数形式下的小数位数小于d,则不足的小数部分用0进行填充。 • e表示指数部分中指数所占的位数。
11.4.4 D编辑符 • D编辑符适用于双精度数据的输出。其一般形式为: • Dw.d • D是英文单词“Double Precision”的首字母,表示“双精度编辑符”。 • w仍然表示输出数据所占的字段宽度;d表示指数部分所占的位数。具体的含义同E编辑符。 • 在使用方法上,D编辑符与E编辑符相似。只是把字母“E”换成“D”,在数据输出时,指数部分的字母“E”用“D”来代替。实际上,F编辑符也可用于双精度数据的输出,和用于实型数据输出相似。但此时可能会由于不能确切估计实际数据的大小而出现“大数印错,小数印丢”的情况。
11.4.5 A编辑符 • E编辑符用于输出指数形式的实数,其一般形式为: • Ew.d[Ee] • E是英文单词“Exponent”的首字母,表示“指数编辑符”。 • w还是表示要输出的“字段宽度”,包含指数部分所占的4个字符的宽度和负数的负号。如果要输出的数据实际宽度超出了w规定的宽度,则在该字段宽度范围内用星号“*”填充;如果输出的数据实际宽度小于w规定的宽度,则在输出数据的前面用空格填充。 • d表示要输出数据的小数位数。小数部分的位数可以由公式w≥d+7来确定,公式中的“7”表示一个小数点、小数点前的0、一个负号和指数部分所占的4位。如果实际数据在指数形式下的小数位数大于d,则多出的小数部分按四舍五入规则进行舍入;如果实际数在指数形式下的小数位数小于d,则不足的小数部分用0进行填充。 • e表示指数部分中指数所占的位数。
11.4.6 L编辑符 • L编辑符适用于逻辑型数据的输出。其一般形式为: • Lw • L是英文单词“Logical”的首字母,表示“逻辑编辑符”。 • w表示输出的逻辑型数据所占的字段宽度。由于逻辑型数据在输出时只显示一个字符,即.TRUE.打印为“T”,.FALSE.打印为“F”。因此,当w大于1时,字符的左端用空格进行填充。
11.4.7 G编辑符 • 既然单独使用F编辑符和E编辑符都有这样或那样的缺点,那么有没有一种编辑符足够“聪明”,可以自行判别哪种数应该用F编辑符进行输出还是用E编辑符进行输出呢? • Fortran提供了这样一种“聪明”的编辑符,即G编辑符。该编辑符对F编辑符和E编辑符的长处进行了综合,能够根据要输出的实数大小来决定用何种格式进行输出,即F型格式和E型格式。当输出的数值过大或过小时会自动采用E型格式,当输出的数值能够用小数形式表达时则用F型格式。G编辑符的一般形式为: • Gw.d[Ee] • G是英文单词“General”的首字母,表示“通用编辑符”。 • w仍然表示输出数据所占的字段宽度;d表示指数部分所占的位数;e表示指数部分数字的位数。具体的含义参考E编辑符。
11.4.8 B、O、Z编辑符 • 二进制(B)、八进制(O)和十六进制(Z)编辑符是Fortran 90标准中新增的编辑描述符,用于整数、实数、字符和逻辑量的输出。其一般形式为: • Bw[.m] • Ow[.m] • Zw[.m] • B、O和Z分别表示“二进制编辑符”、“八进制编辑符”和“十六进制编辑符”。 • w表示输出数据的字段宽度;m表示需要输出的最少数字位数,缺省值为1。如果实际的输出数据宽度少于指定的字段宽度,则数据的左端用空格填充。但对于二进制数,如果以0填补可读性会更好一些。例如00010101显示了l0101所有的8位,此时可以令m=w的方法来强迫数据的开始以0填补。
11.4.9 EN、ES编辑符 • 工程计数法(EN)和科学计数法(ES)也是Fortran 90标准中新增的编辑描述符。两种编辑符的的一般形式为: • ENw.d[Ee] • ESw.d[Ee] • 其中E是英文单词“Exponent”的首字母,N是英文单词“Engineering”的第二个字母,S是英文单词“Scientific”的首字母。 • EN和ES编辑符中的w、d、e与E编辑符中的基本类似,可以参考E编辑符中的相关描述。梁柱编辑符与E编辑符的区别在于: • 采用EN编辑符输出数据时,数据的非指数部分的绝对值一定在1到1000的范围内(除非数据的数值为0),且指数可以被3整除。包括指数部分和负号,整个数据的输出字段宽度是w个字符,小数点后d个字符,指数宽度e是可选的。 • 采用ES编辑符输出数据时,数据的非指数部分的绝对值一定在l到10的范围内(除非数据的数值为0),而非E编辑符的0到1。
11.5 控制格式编辑描述符 • 控制格式描述编辑符在格式语句中的作用是确定文本的显示方式,比如数据在所在行的什么位置进行输出、统计记录中剩余的字符数目、是否输出数据的加号等。下面分别对常见控制格式编辑描述符进行介绍。
11.5.1 X编辑符 • X编辑符是控制格式编辑描述符中最常使用的一种。该编辑符用来在输出数据时产生空格。前面的数据格式编辑描述符在输出数据时,数据之间没有空格。为了避免读数困难,前面的例程在输出时,尽可能每行只输出一个数据。有了X编辑符之后,数据的输出就更为方便了。X编辑符的一般形式为: • nX • 其中n表示要插入的空格数量。Fortran 77标准中允许n为负数,但是Fortran 7的子集以及很多Fortran 90/95编译系统,例如Compaq Visual Fortran、gFortran和G95,并不支持这种用法。
11.5.2 纵向走纸控制符 • 在介绍X编辑符时,提到了格式语句中第一项如果是1X,则在打印设备上可以作为纵向走纸控制符。那么什么是纵向走纸控制符呢? • Fortran中规定:把格式记录中的信息传送到打印设备上(如打印机或终端)时,格式说明中的第一个字符用作纵向间隔控制标志,称为纵向走纸控制符。格式说明中的第一个字符不再被打印出来,而从格式说明中的第二个字符开始打印。 纵向走纸控制符及功能
11.5.3 斜杠编辑符 • 斜杠“/”编辑符的作用是结束本笔记录的输出并开始下一笔记录的输出,其一般形式为: • [r]/ • 其中r为重复系数,该系数必须是一个正的整形常数。如果有两个连续的斜杠,相当于在输出记录中增加一个空行输出;如果在格式编辑符的最后出现斜杠,也要再输出一个空行。用n个连续的斜杠,可以达到输出n-1个空行的效果。下面的代码演示斜杠编辑符的使用效果。 • TEST1112.F90 • ! /编辑符的范例 • PROGRAM TEST1112 • IMPLICIT NONE • WRITE(*, ‘(“ I=”,I3,/,” J=”,I3,/,/,” K=”,I3,/)’)1, 3, 5 • WRITE(*, ‘(“ L=”,I3,/,” M=”,I3,/,” N=”,I3)’)2, 4, 6 • END PROGRAM TEST1112
11.5.4 T,TL和TR编辑符 • T、TL和TR编辑符也称为位置编辑符,其作用从其名字就可以知道适用于控制输出项的输出位置的。这三个编辑符指出将要输出到记录上的下一个字符的位置。它们的一般形式为: • Tn • TLn • TRn • 其中n是非零的正整数。 • T编辑符指明记录上的下一个字符输出到本行第n个字符的位置上。对于行式打印输出,由于记录中的第一个字符被用作纵向走纸控制符,因此Tn的实际作用是将输出位置定位在打印记录的第n-1个字符上。在这个位置之前如果没有其他字符输出,则用空格填充。
11.5.5 冒号编辑符 • 冒号“:”编辑符的作用是当I/O列表中没有更多的数据项时,使格式控制结束。冒号编辑符常常用于FORMAT语句中没有要输出的数据项时结束输出。来看下面的一段代码。 • TEST1114.F90 • ! :编辑符的范例 • PROGRAM TEST1114 • IMPLICIT NONE • PRINT 1,3 • PRINT 2,13 • 1 FORMAT (' I=',I2,' J=',I2) • 2 FORMAT (' K=',I2,:,' L=',I2) • END PROGRAM TEST1114
11.5.6 P编辑符 • P编辑符也称为比例因子编辑符,可用来设置比例因子以改变小数点位置。P编辑符用于实数的编辑描述符,如F、E和G编辑符。编辑符的作用范围延续到下一个比例因子的设置处。P编辑符的一般形式为: • kP • 其中k是一个有符号整数(为正时可省略正号),用于指定小数点向左或向右移动几位。k的取值范围在-128至127之间。在每一个输入输出语句开始时,比例因子都会被初始化为0。输出时,正k向右移,负k向左移(输入时正好相反)。
11.5.7 SP,SS,S编辑符 • SP,SS和S编辑符的作用是在数字的输出字段中确定是否添加加号“+”。SP编辑符为其后所有正数的输出添加加号“+”;SS编辑符则用于取消SP编辑符的作用;S编辑符重新储存SS使其后的正数不输出加号。下面的代码段演示了这三个编辑符的作用效果。 • i = 251 • WRITE (*, 100) i, i, i, i, i • 100 FORMAT (I5, SP, I5, SS, I5, SP, I5, S, I5) • 程序将打印以下结果: • 251 +251 251 +251 251
11.5.8 BN,BZ编辑符 • BN和BZ编辑符也称为空格编辑符,其作用在于确定输入时的空格所代表的意义。BN编辑符通知系统将输入时没有数据的字节处理成“无意义”,即输入字段宽度内的空格什么也不代表,仅仅是占位符;BZ编辑符则通知系统将输入时没有数据的字节全部处理为“0”,即输入字段宽度内的空格代表“0”。
11.6 字符串编辑描述符 • 字符串编辑符主要用于字符常量的格式化输出。常见的字符串编辑描述符有两种,即撇号编辑符和H编辑符。在使用上,H编辑符在Fortran 90标准中已经被废弃,在Fortran 95标准中则进一步被废除。下面分别对这两种编辑符进行介绍。
11.6.1 撇号编辑符 • 撇号编辑符(单撇号“'”或双撇号“"”)用来插入所需的字符串,其一般形式为: • “要插入的字符” • ‘要插入的字符’ • 如果要输出的字符中包含撇号,则应该使用两个连续的撇号来代表一个被输出的撇号。
11.6.2 H编辑符 • H编辑符是Fortran 77等老标准的遗留产物,在Fortran 90/95标准中已经相继被废弃和废除。但是,一些较老的Fortran程序中仍可能会遇到这种编辑符,这里作一简单介绍。H编辑符用来输出字符常量,其一般形式为: • nH<字符串> • 其中n为字符串中的字符个数。H编辑符在作用上与撇号编辑符相似,但使用上不甚方便。例如下面的两句代码的作用是完全一致的: • WRITE(*, ‘(‘The value of A is’, F10.5)’) A • WRITE(*, ‘(17HThe value of A is, F10.5)’) A • 使用H编辑符时必须准确的确定字符串中的字符数量,否则很容易产生编译错误。例如下面的代码段就会产生编译错误: • WRITE(*, ‘(18HThe value of A is, F10.5)’) A
11.7 编译器扩展的格式编辑描述符 • 除了Fortran 77/90/95标准中规定的标准格式编辑描述符外,一些Fortran编译器还会提供一些扩展的格式编辑描述符。在有些情况下,这些扩展的格式编辑描述符会使编写的应用程序增色不少。本小节将介绍两种Compaq Visual Fortan编译器提供的两种扩展格式编辑描述符。
11.7.1 反斜杠“\”编辑符和美元“$”编辑符 • 反斜杠“\”编辑符和美元“$”编辑符在格式输入输出语句中的作用相同:都是在输出一个记录行后取消回车符,接着输出的记录会紧接在前一个记录的后面位于同一行。 • 这两个编辑符常用于输出的字符串与输入数据需要显示于屏幕同一行的情形。这两种编辑符在使用方式上完全一样,只要放在格式说明列表的最后就可以了。例如下面的一段代码: • WRITE(*, 100) • 100 FORMAT (' ENTER RADIUS VALUE: ',$) • READ(*, *) RADIUS • 该段代码首先会在屏幕的第一行显示如下内容: • ENTER RADIUS VALUE:
11.7.2 可变格式编辑符 • 在前面的格式说明语句中,控制编辑描述符中多是常数。例如整型变量对应的I编辑符中,规定的字段宽度是固定的,如果数据的实际长度没有那么宽,则多出的部分就只能用空格填充。这就使数据的输出不太美观。 • 在Compaq Visual Fortran中提供了可变格式编辑符来解决这类问题,即用尖括号括起来的数值表达式来表示可变的格式。该编辑符的一般形式如下: • <数值表达式> • 其中的数值表达式可以是常量表达式,也可以是变量表达式。可变格式编辑符通常用作I编辑符中的可变字段宽度定义、可变重复系数等。
11.8 I/O列表 • I/O列表也叫做输入/输出列表,它罗列了需要进行输入/输出操作的所有变量。在Fortran中,针对I/O列表有一些特殊的用法和语句,如这里介绍的NAMELIST语句。本节将主要介绍同I/O列表相关的知识。
11.8.1 NAMELIST语句 • NAMELIST语句是Fortran 90/95标准中正式收录的一种特殊输入/输出方法。其实早在Fortran 77时代,一些编译器就已经开始支持这种输入输出用法。但是,Fortran 77时代的NAMELIST语句没有统一的标准,各家编译器厂商大多各行其道,怎么方便怎么来。这种情况直到Fortran 90/95时代才得到了改观。在新标准中,NAMELIST语句作为一种正式的标准语句,开始有了统一的使用格式。 • NAMELIST语句也称为名称列表语句,其作用就是将一组变量同一个列表组名相关联。该语句将一组相关的变量封装在一起,在对这些变量进行输入/输出操作时,只需要确定在输入/输出语句中确定用哪一个NAMELIST就可以了。也就是说这个列表组名可以在输入/输出语句直接被引用,其中所封装全部变量会依次被输入/输出相应的数据。
11.8.2 I/O列表实体 • 在使用输入/输出语句(如READ、WRITE、PRINT语句)进行输入输出操作时,需要知道如何进行数据传递和传递什么数据的信息。其中如何进行数据传递已经在前面的小节中进行了较为详细的介绍,而传递什么数据则是由I/O列表(io-list)中列出的将要进行输入/输出操作的项来确定的。也就是说,I/O列表提供了将要进行输入/输出操作的数据的相关信息。其实在前面的章节中早就已经遇到过I/O列表,只是没有专门列出来进行说明。本小节专门将其罗列出来,将I/O列表实体的有关知识进行一个简单的总结。