错误:格式字符串中的P描述符后需要逗号

时间:2019-03-01 12:54:03

标签: fortran

当我尝试使用gfortran编译calrank.for(CALRANK_v7.0.0_L140912.zip)时,出现此错误:

> gfortran  -m64 -c -o calrank.o calrank.for
calrank.for:1922:32:
         write(io,'(2f10.3,1p1000(2x,e16.7,1x,2a10,1x))')
                                1
Error: Comma required after P descriptor in format string at (1)

当我做逗号时,我遇到了同样的错误。
我只注意到该代码是在LF95之前编译的。

   subroutine xycout(io,nrank,nsp)
      use userinf
      use header
      use rankdata

      implicit none

    integer :: io,nrank,nsp
      integer :: k,ir,is,i
      character(len=20)   :: head1,head2,head3
      character(len=40)   :: add1x,add2x,add3x
      character(len=40)   :: add1(nsp),add2(nsp)
      character(len=40)   :: add3(nsp)
 ......
 c --- Loop over receptors to write data records
      do ir=1,ntotrec(k)
         write(io,'(2f10.3,1p1000(2x,e16.7,1x,2a10,1x))')
     &                   xreckm(ir,k),yreckm(ir,k),
     &                  (xounit(is,k)*rankvalue(ir,is,nrank),
     &                   arankdate(ir,is,nrank),
     &                   aranktime(ir,is,nrank),is=1,nspout(k))
      enddo

      return
      end

一些变量在代码的其他位置定义为:

c --- Real arrays for header (derived)
      allocate (xreckm(mxrec,k),yreckm(mxrec,k))
c --- Modified units multiplier
      allocate (xounit(mxspout,k))
      c --- Array of values (all species, receptors) for requested ranks
      allocate (rankvalue(ntotrec(k),nspout(k),n_ranks))
      allocate (arankdate(ntotrec(k),nspout(k),n_ranks))
      allocate (aranktime(ntotrec(k),nspout(k),n_ranks))
c --- Integer arrays for header
      deallocate (ndrec,nctrec,nspout,i2dmet,iutmzn)

2 个答案:

答案 0 :(得分:2)

您应该完全按照错误消息的说明进行操作,在p描述符后面加上逗号:

write(io,'(2f10.3,1p,1000(2x,e16.7,1x,2a10,1x))')

如果您不知道什么是p描述符,请参见https://docs.oracle.com/cd/E19957-01/805-4939/z4000743a6e2/index.html或有关Fortran编辑描述符的任何教程。正如史蒂芬·莱昂内尔(Steven Lionel)在下面的评论所述,您可以在普通数据编辑描述符之前使用p描述符,而无需使用逗号。

答案 1 :(得分:2)

@francescalus建议我扩大评论范围。

首先,Fortran通常需要在两个“格式项”之间使用逗号。格式项是带有或不带重复计数的编辑描述符(F,E等),或者是带括号的格式项组(可能有自己的重复计数;提到了@Vladimir F *-这是“无限重复计数”,并且只能与带括号的组一起使用。

逗号可以省略:

  • 在P编辑描述符和紧随其后的F,E,EN,ES,EX,D或G编辑描述符之间,可能在重复说明之前,
  • 未出现可选的重复说明时,在斜杠编辑描述符之前,
  • 斜杠编辑描述符之后,或者
  • 在冒号编辑描述符之前或之后

现在,对于P编辑描述符,这将设置比例因子,这确实很奇怪,并且根据您执行的编辑类型的不同,其效果也大不相同。它也是“粘性”的,并适用于该格式的所有后续编辑。

在输入时,它将导致读取值除以10 ** k,其中k是比例因子(2P表示k = 2,依此类推)。因此,如果输入的字符为123且2P有效,则该值读取为1.23。同样,如果-2P有效,则123表示为12300。输入中的小数点不会更改此值,但是指数会删除缩放比例。因此,以2P读取的1.23是.0123,而1.23E0是1.23。

在使用F编辑的输出上,它会使输出值乘以10 ** k,从而反转输入方案。

您可能会问为什么?答案在于打孔卡,打孔卡是1950年代至70年代使用的一种输入(有时是输出)形式。它们有80列,而在小数点上浪费一列可能是一个问题。因此比例因子允许人们省略小数点,但仍然得到分数。

但是等等,它变得陌生了!在使用E和D编辑的输出中,比例因子仅确定小数点左侧的前导位数(以及随后的指数减少。因此,对于1.23的值和2P,E11.3的格式,您会得到b12.300E-01(除非SP生效,否则b =空白,这是第二天的答复。)

对于G格式的输出?甚至更奇怪。如果该值在获得与F格式等效的范围内,则比例因子无效,否则其行为类似于E。

最后,比例因子对EN,ES或EX编辑没有影响。 (例如,这是F2018的十六进制浮点输出功能。)

P格式的一个好用法是在使用整数而不是实数进行货币计算时,因为后者可能会失去精度(例如.01,没有精确的二进制浮点表示形式。)假设您要处理的值是aren不会太大,您可以将美元和美分读为-2P格式的整数,而不会因加,减和乘而损失任何便士。我曾经以这种精确的方式编写抵押计算器。