假设我正在尝试写出一个如下所示的CSV文件头:
STRING1 2001, 2002, 2003, 2004,
这样做的一些变量格式的Fortran90代码是
INTEGER X<Y X=2001 Y=2004 WRITE(6,'(A,(999(5X,I4,",")))') ' STRING1',(y,y=X,Y)
“999”重复(5X,I4,“,”)格式结构,需要多次完成(最多999次)。假设X和Y可能会发生变化,因此循环迭代次数也可能会发生变化。
但是如果我希望标题看起来像这样,在序列的末尾加上一个额外的字符串,比如
STRING1 2001, 2002, 2003, 2004, STRING2
...我已经尝试在格式字符串的末尾添加另一个A,但是重复的变量格式结构显然不知道它需要在完成整数时“转义”,因此它会出错。
我可以通过在格式字符串中包含'ADVANCE =“no”'来解决这个问题,并使用新的WRITE语句打印第二个字符串以获得我从根本上想要的内容,但有没有办法可以用单格式结构?
[注意:请不要使用角括号答案;这适用于GNU gfortran,它不支持该扩展名]
答案 0 :(得分:4)
C&#39;周一人,加入该计划!
这是标准的Fortran 2008:
WRITE(6,'(A,*(5X,G0,:,","))') ' STRING1',(y,y=X,Y), ' STRING2'
我很确定gfortran支持&#34;无限组重复计数&#34;。在Fortran 2008中扩展了G格式以支持任何内部数据类型,宽度为零意味着“最小字符数”。&#34;冒号是一个F77功能,可以阻止发出尾随逗号。
有了这个,ifort给了我:
STRING1 2001, 2002, 2003, 2004, STRING2
FWIW,我对你重复使用y作为循环控制变量感到不满意,因为这不是一个语句实体,并且会在循环结束时设置为2005。请使用单独的变量!
答案 1 :(得分:1)
program test
character(len=20) :: N_number
integer :: X,Y
X=2001
Y=2004
write(N_number,*) Y-X+1
write(6,'(A,('//TRIM(N_number)//'(5X,I4,","))A)') ' STRING1',(y,y=X,Y),' STRING2'
end program test
答案 2 :(得分:1)
令人遗憾的是,变量格式扩展不是标准的。既然不是,大多数人都推荐@anonymous显示的方法。也就是说,您首先使用internal-write语句将整数转换为字符串,而不是使用<N>
。然后将此N
的字符串表示形式插入格式表达式中,以便在write
或print
语句中使用。 1
或者,您可以将数组中的数值转换为字符串。 2 它也非常简单。在下面的例子中,我展示了这两种方法。
program writeheader
implicit none
character(len=80) :: string1, string2, string3, fmt, num
integer, dimension(10) :: array
integer :: x,y,len
continue
string1 = "begin"
string3 = "end"
array = [1:10]
x = 3
y = 7
!! Method 1: Convert the variable number of values into a string, then use it
!! to create the format expression needed to write the line.
write(num, "(i)") y - x + 1
fmt = "(a,', ',(" // trim(adjustl(num)) // "(i0:', ')), a)"
print fmt, trim(string1), array(x:y), trim(string3)
!! Method 2: Convert the desired range of array values into a character string.
!! Then concat, and write the entire line as a string.
write(string2, "(*(', ',i0))" ) array(x:y)
len = len_trim(string2) + 1
print "(a)", trim(string1) // string2(1:len) // trim(string3)
end program writeheader
在示例中显示的任何一种情况下,输出如下:begin, 3, 4, 5, 6, 7, end
1 如果我能找到它,我会在SO上添加一个很好的解决方案链接,创建一个生成格式表达式的函数。
2 我在这里直接使用了数组边界,作为隐含的do循环的替代。