编写很长的字符串时,Fortran 中的自动换行符

mft*_*mbn 5 fortran

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

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

只要字符串小于 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
Run Code Online (Sandbox Code Playgroud)

如果我使用 Intel 的 Fortran 编译器进行编译,则会得到以下输出:

 First line
 This is line number: 1
 This is line number: 2
 This
 is line number: 3
Run Code Online (Sandbox Code Playgroud)

使用 gfortran 给出了预期的输出:

 First line
 This is line number: 1
 This is line number: 2
 This is line number: 3
Run Code Online (Sandbox Code Playgroud)

Mat*_*t P 6

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

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

! This is the output:
 ************************** This is an 84-character string ****************
 *****
Run Code Online (Sandbox Code Playgroud)

请注意,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
Run Code Online (Sandbox Code Playgroud)

等等。


更新:我已经查看了您添加到原始帖子中的代码。请注意,在 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
Run Code Online (Sandbox Code Playgroud)

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


Vla*_*r F 5

您显示的代码没有在字符串中包含自动换行符。你必须拿出一些证据来证明这一点,但我认为你的前提是错误的。字符串中不存在这样的中断。

发生的情况是,您正在打印字符串,并且打印过程使用换行符。现在我们有了你的代码,很明显它就是这一行

write(*,*) long_string
Run Code Online (Sandbox Code Playgroud)

,*)是列表导向的格式。编译器在如何以这种格式打印内容方面有很大的自由度。您必须使用某种显式格式才能进行更精细的控制。开始你的实验(a)

write(*,'(a)') long_string
Run Code Online (Sandbox Code Playgroud)