从英特尔移植到GNU gfortran时的可变格式语句

时间:2017-09-22 19:48:18

标签: fortran gfortran fortran90

假设我正在尝试写出一个如下所示的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,它不支持该扩展名]

3 个答案:

答案 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的字符串表示形式插入格式表达式中,以便在writeprint语句中使用。 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循环的替代。