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
In Fortran, a statement must start on a new line. If a statement is too long to fit on a line, it can be continued with the following methods: If a line is ended with an ampersand, &, it will be continued on the next line. Continuation is normally to the first character of the next non-comment line.
In fixed-form source, lines can be longer than 72 characters. Columns 73 through 96 are ignored. Standard Fortran 90 allows 72-character lines.
We can either print blank records or explicitly add a newline character. NEW_LINE('a') is likely to have an effect like ACHAR(10) or CHAR(10,KIND('a')) . NEW_LINE('a') could also be used in the format string but this doesn't seem to add much value beyond slash editing.
A line of Fortran 90 code can have a maximum of 132 characters. An ampersand (&) is placed at the end of a line to indicate that it continues on the next line. At most 39 continuation lines are permitted.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With