在Fortran中将数据按列写入文件

7

我需要在Fortran 90中将一些数据写入文件。如何使用WRITE (*,*) input使值以的形式分组?WRITE总是在每次调用后放置一个新行,这就是问题所在。

代码示例:

open (unit = 4, file = 'generated_trajectories1.dat', form='formatted')

do time_nr=0, N
   write (4,*) dble(time_nr)*dt, initial_traj(time_nr)
end do

现在的重点是将它写成单独的列。


1
@Alex,你能具体说明一下吗?你想要在单独的列中拥有什么?你需要一个包含N行和两列的输出文件,一列是dble(time_nr)*dt,另一列是initial_traj(time_nr)吗?还是你需要一个包含一行和2*N列的输出文件? - Chris
1
请提供声明,以便我们建议适当的格式。实数?I格式答案中的示例不起作用。 - M. S. B.
4个回答

13

你可以使用隐含的 DO 循环将值作为单个记录进行编写。比较以下两个示例:

integer :: i

do i=1,10
   write(*,'(2I4)') i, 2*i
end do

它生成:

1   2
2   4
3   6
...

使用隐式 DO 循环,可以将其重写为:

integer :: i

write(*, '(10(2I4))') (i, 2*i, i=1,10)

这个会产生:

1   2   2   4   3   6   ...

如果元素数量在编译时不固定,您可以使用<n>扩展(不支持gfortran):

write(*, '(<n>(2I4))') (i, 2*i, i=1,n)

该语句从变量 n 中获取 (2I4) 编辑描述符重复的次数。在 GNU Fortran 中,您可以使用内部文件首先创建适当的编辑描述符:

character(len=20) :: myfmt

write(myfmt, '("(",I0,"(2I4))")') n
write(*, fmt=myfmt) (i, 2*i, i=1,n)

当然,它也适用于列表指定输出(即以*格式输出):

write(*, *) (i, 2*i, i=1,10)

3
尽管gfortan不支持<n>扩展,但它支持使用*来指定可变数量的格式项。这个无限制格式项的特性是Fortran 2008标准的一部分。 - M. S. B.
@M.S.B. 我不知道F2008中有这个功能 - 真的是非常受欢迎的补充。 - Hristo Iliev
@HristoIliev,如果我要打印实数,应该怎么做?关于格式化,像“(10(2I4))”这样的格式不起作用。 - L.K.
@lavkush,实数的相应编辑描述符为EF-请参见此处G可用于根据要打印的值和输出字段的宽度自动选择EF之间进行选择。 - Hristo Iliev
感谢您提供关于<n>扩展的指针 - 在英特尔编译器中完美运行。 - Adrian

4
这真的取决于你要写入文件的数据是什么(即你是否有一个循环内的标量或数组...)。你能在你的问题中包含对此的描述吗?
如果您试图多次将标量写入同一行,请尝试使用 “非预进I/O” ,将关键字参数 advance="no" 传递给写语句,例如:
integer :: x

do x = 1,10
  write(*, fmt='(i4,1x)', advance="no") x
end do

然而,请注意非进阶I/O可能会带来意外惊喜。


这是一个循环完成的,所以不前进也可以完成它。但是,我得到了一些类似二进制的文本,而不是漂亮的数字列。因此,我想格式上出了问题。GEdit甚至无法打开该文件。 - alex
你能否发布一份代码的最小示例?数据如何写入文件取决于传递给打开命令的参数,没有你的代码,无法确定具体情况。 - Chris

0

答案取决于你对Chris的问题的回答。如果你想要一行代码,那么你必须使用Chris所描述的非进阶IO。否则,使用多个格式化写语句将始终得到多行。

此外,您可能需要使用格式化IO而不是列表指定(*) IO。列表指定IO的规则很松散。不同的编译器可能会产生不同的输出。对于许多输出项,换行符可能会使输出行过长。

这里有一个格式,如果您的所有变量都是实数,则应该可以工作:

write (4, '( *(2X, ES14.6) )', advance="no" )

0

好吧,那么怎么看待老旧的$编辑描述符呢:

write(*, fmt='(i4,$)') x

在你的循环后面记得加上 write(*,*)...


标准的Fortran语言中没有这样的东西。 - Vladimir F Героям слава
是的,这是一种非常普遍的扩展,以至于你会忘记它是一个扩展。 - agentp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接