当写一个很长的字符串时,Fortran中的自动换行符

时间:2018-01-18 16:35:40

标签: fortran

我在fortran中有一个字符串,我在循环中扩展:

character(:), allocatable :: string
...
do i = 1, n
  string = string // "some stuff depending on i"
end do

只要字符串小于80个字符,这就可以正常工作。当达到80个字符时,字符串中会包含换行符。

有谁知道为什么会发生这种情况,如果有机会避免这种情况?

我有以下完整的例子:

program string

  implicit none

  character(:), allocatable :: long_string
  character(:), allocatable :: line

  integer      :: i
  character(8) :: idx

  line = " This is line number: "

  long_string = "First line" // NEW_LINE('A')

  do i = 1, 3
    write(idx, "(I8)") i
    long_string = long_string // line // adjustl(trim(idx)) // NEW_LINE('A')
  end do

  write(*,*) long_string

end program

如果我使用英特尔的Fortran编译器编译,我会得到以下输出:

 First line
 This is line number: 1
 This is line number: 2
 This
 is line number: 3

使用gfortran给出预期的输出:

 First line
 This is line number: 1
 This is line number: 2
 This is line number: 3

3 个答案:

答案 0 :(得分:2)

您显示的代码中没有自动换行符包含在字符串中。你必须出示一些证据,但我的主张是你的前提是错误的。字符串中没有这样的中断。

您正在打印字符串,打印过程使用换行符。现在我们有了你的代码,很明显它就是

write(*,*) long_string

,*)是列表导向的格式。编译器在如何以这种格式打印东西的方式上有很多自由。您必须使用某种显式格式才能获得更好的控制权。使用(a)开始实验:

write(*,'(a)') long_string

答案 1 :(得分:2)

正如您所注意到的,在开始新行之前,列表定向输出将自动打印最多80个字符:

character(len=:), allocatable :: a
a = "************************** This is an 84-character string **************************"
print *, a

! This is the output:
 ************************** This is an 84-character string ****************
 *****

请注意,80个字符的限制包括所有打印和非打印字符,包括使用列表定向输出时自动插入的前导空格。我看了,但是我无法确定是否有办法可以更改此默认行为,或者是否由Fortran标准或其他任何内容指定。

为了完成,我将展示我正在谈论的内容。处理此问题的最佳方法是定义格式,如前面的答案中所述。您可以非常轻松地为字符串执行此操作:

! print everything in the string:
print "(a)", a
! output:
************************** This is an 84-character string **************************

! or, define the printed field width:
print "(a34)", a
! output:
************************** This is

等等。

更新:我已查看您添加到原始帖子的代码。请注意,在DO循环中创建long_string后,字符串长度超过80个字符。然后使用列表导向输出进行打印时,ifort的结果是有意义的:任何超过80个字符(包括前导空格和换行符)都会自动在新行上继续。

请注意,当您使用adjustl(trim(idx))时,您仍然会得到一个长度为8个字符的字段。我认为你的意思是使用trim(adjustl(idx))。如果你这样做,仍然使用列表导向的输出来写long_string,那么输出如下:

First line
This is line number: 1
This is line number: 2
This is line number
: 3

因此,您再次在输出结尾处获得额外的“意外”行,因为long_string的长度超过80个字符。幸运的是,解决方案是(再次)使用字符格式"(a)"。由于您已将换行符放在所需的位置,因此您将获得您希望的输出。

答案 2 :(得分:1)

有时候,即使我们知道进行更改是正确的,我们也懒得这样做。

英特尔正在做正确的事情,将每行中的长行中断为80个字符,以获得更好的人为阅读体验。为“写”功能提供显式格式字符串也是正确的。但是,当我从GNU切换到Intel编译器时,我发现自动换行符使我的后处理脚本出现故障,并且可能需要一些时间才能将源代码中的字符串格式从星号(列表导向)更新为显式格式。

Intel提供了禁用自动换行符的选项。请参阅“英特尔®Fortran编译器17.0开发人员指南和参考”,您将找到该选项

-no-wrap-margin

将其添加到编译器标志。继续正常的工作流程。找点时间以后再更新代码。