我正在尝试使用fortran写出逗号分隔的文件,以便导入到另一个商业软件包中。问题是我的数据列数量未知。我的输出需要看起来像这样:
a_string,a_float,a_different_float,float_array_elem1,float_array_elem2,...,float_array_elemn
会导致某些内容看起来像这样:
L1080,546876.23,4325678.21,300.2,150.125,...,0.125
L1090,563245.1,2356345.21,27.1245,...,0.00983
我有三个问题。一,我宁愿将元素紧密分组(变量列宽),二,我不知道如何在格式语句中定义可变数量的数组元素,三,数组元素可以跨越大范围 - 也许12个数量级。以下代码在概念上做了我想要的,但变量'n'和缺少列宽定义会引发错误(当然):
WRITE(50,900) linenames(ii),loc(ii,1:2),recon(ii,1:n)
900 FORMAT(A,',',F,',',F,n(',',F))
(我应该注意n在运行时是固定的。)当我执行WRITE(50,*)时,write语句执行我想要的操作,除了它是宽度分隔的。
我认为这个帖子几乎回答了我的问题,但我很困惑:SO。现在我有一个用awk修复问题的shell脚本,但是这个解决方案是......不优雅的。我可以做一些操作来使输出成为一个字符串,然后只写它,但我宁愿尽可能避免使用该选项。
我在Fortran 90中这样做,但我想尽量保持我的代码尽可能向后兼容。
答案 0 :(得分:1)
接近你想要的格式是f0.3,这将不给出空格和固定数量的小数位。我想如果你想要删掉尾随的零,你需要做一些工作。
写入语句中的“n”可能大于数据值的数量,因此一个(旧学校)方法是在那里放一个大数字,例如100000.现代fortran确实有一些语法来指定无限重复,我相信有人会提供这个。
----编辑 无限重复是你可能猜到的星号......并且在f2008中显然是“全新的”
答案 1 :(得分:1)
为了确保行中的条目之间没有空格,您可以在字符变量中单独编写它们,然后使用fortran中的adjustl()
函数将它们打印出来:
program csv
implicit none
integer, parameter :: dp = kind(1.0d0)
integer, parameter :: nn = 3
real(dp), parameter :: floatarray(nn) = [ -1.0_dp, -2.0_dp, -3.0_dp ]
integer :: ii
character(30) :: buffer(nn+2), myformat
! Create format string with appropriate number of fields.
write(myformat, "(A,I0,A)") "(A,", nn + 2, "(',',A))"
! You should execute the following lines in a loop for every line you want to output
write(buffer(1), "(F20.2)") 1.0_dp ! a_float
write(buffer(2), "(F20.2)") 2.0_dp ! a_different_float
do ii = 1, nn
write(buffer(2+ii), "(F20.3)") floatarray(ii)
end do
write(*, myformat) "a_string", (trim(adjustl(buffer(ii))), ii = 1, nn + 2)
end program csv
上面的演示仅适用于一个输出行,但您可以轻松地在相应的块周围编写一个循环,以便为所有输出行执行它。此外,如果您愿意,可以为不同的条目选择不同的数字格式。