mftrmbn
mftrmbn

Reputation: 123

Automatic line break in Fortran when writing a very long string

I have a string in fortran that I extend in a loop:

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

This works fine as long as string is smaller than 80 characters. When 80 characters are reached a line break is included into the string.

Does anyone know why this happens and if there is a chance to avoid this?

I have the following full example:

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

If I compile with Intel's Fortran compiler, I get the following output:

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

Using gfortran gives the expected output:

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

Upvotes: 9

Views: 6599

Answers (3)

ppppplv
ppppplv

Reputation: 471

Sometimes, even we know it is right to make the change, we are too lazy to do that.

Intel is doing the right thing by breaking long lines to 80 characters per line, for better experience of human reading. It is also right to provide the 'write' function with explicit format string. But when I was switching from GNU to Intel compilers, I found that the automatic linebreak made my post-processing script malfunction and it might take some time to update the string format in my source code from asterisk (list-directed) to explicit formatting.

Intel provides the option to disable the automatic linebreak. Refer to "Intel® Fortran Compiler 17.0 Developer Guide and Reference", you will find the option

-no-wrap-margin

Add it to compiler flags. Continue your normal work flow. And find some time to update your code later.

Upvotes: 5

Matt P
Matt P

Reputation: 2357

As you've noticed, list-directed output will automatically print up to 80 characters before beginning a new line:

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

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

Notice that the 80-character limit includes all printed and non-printing characters, including the leading space automatically inserted when using list-directed output. I looked, but I couldn't find out whether there are ways you can change this default behavior, or if it is specified by the Fortran standard or whatever.

To be complete, I'll demonstrate what I'm talking about. The best way to deal with this is to define a format, as already suggested in a previous answer. You can do this for character strings very easily:

! 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

And so on.


UPDATE: I have reviewed the code you've added to your original post. Notice that after you create long_string in the DO loop, the string length exceeds 80 characters. When you then print using list-directed output, the result with ifort makes sense: anything exceeding 80 characters (including leading white spaces and the newline characters) will automatically continue on a new line.

Notice, when you use adjustl(trim(idx)) you still end up with a field 8 characters long. I think you mean to use trim(adjustl(idx)). If you do this, and still use list-directed output to write the long_string, then the output looks like:

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

So, you get that extra "unexpected" line at the end of the output again, because the length of long_string exceeds 80 characters. Luckily, the solution is to (again) just use the character format "(a)". Since you've placed the newline characters where you want them, you'll get the output you are hoping for.

Upvotes: 6

There is NO automatic line break included into a string by the code you show. You must show some evidence for it, but my claim is that your premise is wrong. There is no such break in the string.

What happens is that you are printing the string and the printing process uses line breaks. Now that we have your code it is clear that it is the line

write(*,*) long_string

the ,*) is the list-directed format. The compiler has a lot of freedom in the way how to print stuff in this format. You must use some explicit format to have finer control. Begin your experiments with (a):

write(*,'(a)') long_string

Upvotes: 5

Related Questions