【问题标题】:Fortran: output large array - exceeded length, split on two linesFortran:输出大数组 - 超出长度,分成两行
【发布时间】:2014-07-11 23:17:09
【问题描述】:

在 Fortran 程序中,我需要将数组写入具有特定格式的文件中。 我非常适用于较小的数组(例如,下面示例中的 alen=10),但不适用于较大的数组:然后它将每行分成两部分,就好像超过了每行的最大字符数一样。

示例(与我程序中的结构非常相似):

PROGRAM output_probl
IMPLICIT NONE

INTEGER, PARAMETER :: alen=110          
DOUBLE PRECISION, DIMENSION(alen)::a
INTEGER :: i,j

OPEN(20,file='output.dat')
30  format(I5,1x,110(e14.6e3,1x))

DO i=1,15
 DO j=1,alen
  a(j)=(i*j**2)*0.0123456789
 ENDDO
 write(20,30)i,(a(j),j=1,alen)
ENDDO

END PROGRAM output_probl

它可以正确编译和运行(使用 Compaq Visual Fortran)。只是输出文件有误。例如,如果我将每个数组项的字段宽度从 14 更改为 8,它会正常工作(这当然不是一个令人满意的解决方案)。 我考虑了一个不合适的默认最大记录长度,但找不到如何更改它(即使使用似乎不起作用的 RECL - 如果您认为应该,欢迎使用 RECL 的具体示例)。

这可能是基本的,但我已经坚持了一段时间...欢迎任何帮助,非常感谢!

【问题讨论】:

  • 这应该可以正常工作。您确定无论您使用什么视图文件都不会自动换行吗?
  • 其实是的,你是对的。我正在对输出文件进行后处理,尽管它在过去很长一段时间内都运行良好,但它并没有工作。实际上,与数组大小增加相关的变化(我认为导致输出错误)也与输出格式的问题(用 * 填充的字段)有关,因为只有一个极值。直到你的评论让我使用另一个输出正确显示的查看程序,我才发现它,这让我在别处寻找。 @Vladimir F,也谢谢你 - 你的信息也帮助我解决了 recl 的问题。

标签: fortran


【解决方案1】:

为什么不进行流式访问?对于顺序,总是有一些依赖于处理器的记录长度限制。

PROGRAM output_probl
IMPLICIT NONE

INTEGER, PARAMETER :: alen=110          
DOUBLE PRECISION, DIMENSION(alen)::a
INTEGER :: i,j

OPEN(20,file='output.dat',access='stream', form='formatted',status='replace')
30  format(I5,1x,110(e14.6e3,1x))

DO i=1,15
 DO j=1,alen
  a(j)=(i*j**2)*0.0123456789
 ENDDO
 write(20,30)i,(a(j),j=1,alen)
ENDDO

END PROGRAM output_probl

作为说明,我会为格式字符串使用字符变量,或者将其直接放在 write 语句中,而不是带有标签的 FORMAT 语句。

Fortran 95 版本:

PROGRAM output_probl
IMPLICIT NONE

INTEGER, PARAMETER :: alen=110          
DOUBLE PRECISION, DIMENSION(alen)::a
INTEGER :: i,j,rl
character(2000) :: ch

inquire(iolength=rl) ch

OPEN(20,file='output.dat',access='direct', form='unformatted',status='replace',recl=rl)
30  format(I5,1x,110(e14.6e3,1x))

DO i=1,15
 DO j=1,alen
  a(j)=(i*j**2)*0.0123456789
 ENDDO
 write(ch,30)i,(a(j),j=1,alen)
 ch(2000:2000) = achar(10)
 write(20,rec=i) ch
ENDDO

END PROGRAM output_probl

【讨论】:

  • 感谢@Vladimir F,但除非我错了,否则这是 Fortran 2003 独有的功能吗?我在寻找一个更通用的解决方案(程序很旧)......
  • 关于您的注释,@Vladimir F,我同意 - 如果 'alen' 必须更改,这通常也允许更新格式(然后必须将其包含在格式字符串的字符变量中)。上面的代码是次优的(来自旧程序......)
  • 查看我的直接访问版本的编辑。可以稍微改进一下,根据需要调整缓冲区。
  • 流访问很棒,但是,AFAIK,pgi 还不支持它:-/。说真的 Portland Group ——该标准已经有 10 年历史了,我们为您的编译器支付了多少钱??? ;-P
  • 你必须有一个旧版本,PGI 声称已经支持 FULL Fortran 2003。
【解决方案2】:

下面的程序应该测试。使用 Absoft 编译器,它适用于 n=10000、10 个字符的单词,即一行 100000 个字符宽(加上一对)。使用 G95,我收到一条消息“没有足够的存储空间来处理此命令”,用于 n=5000(n=4000 有效)。 字符*10,维度(:),可分配::测试 整数,维度(:),可分配::itest

1 write(,)'输入 n > 0' 读,n 如果(n.le.0)那么 write(,)'需要值 n > 0' 去 1 万一 写(,*)'n=',n 分配(测试(n),测试(n))

  write(test,'((i10))')(i,i=1,n)
  write(*,*)test

  open(10,file='test.txt')
  write(10,*)test
  write(*,*)'file test.txt written'
  close(10)

  open(11,file='test.txt')
  read(11,*)itest 
  write(*,*)itest
  end

【讨论】:

    猜你喜欢
    • 2021-01-02
    • 2016-03-09
    • 1970-01-01
    • 2015-10-22
    • 2020-08-15
    • 1970-01-01
    • 2011-04-20
    相关资源
    最近更新 更多