I have a Fortran 77 code that shows a comment in the first column and written double precision in the same line. now my text editor (Notepad++) is showing that as a statement. I am confused if it is a statement or a comment.
* double precision Ct,Jt,PDt,AeA0t,Zt,Cq,Jq,PDq,AeA0q,Zq,
* &Kt,Kq,Eta,J,PD,AeA0
First, the text editor syntax highlighting is not something you can trust 100%. It is just there to help you, but it can be wrong and it can differ from an editor to an editor.
Second, if that code compiles, it must be a comment. Otherwise the ampersand & would cause an error. The ampersand can be used in the sixth column to continue the previous line, but it has to be the first character of the line.
It's a comment. If there's anything other than a whitespace in the first column of a line in a fixed-form fortran (That is Fortran up to F77), it's a comment.
These variables are not declared, but if the code doesn't have an implicit none, they would be implicitly declared, some as REAL, some as INTEGER.
Related
A line of code like this:
write(*,*) a,b
will produce as an output a and b separated by one tab. How can I write an output with aand b separated by two tabs?
Your line will typically not produce any tab character, but some number of blank (space) characters. If you want two tab characters, you have to use their ASCII code 9.
write(*,'(4g0)') a, achar(9), achar(9), b
Note the explicit format '(4g0)' used to avoid unwanted blank characters. With the g0 descriptor it will work for any type of a and b.
The <tab>-character is not a part of the Fortran character-set. So when you add it to your source code, most compilers should
complain [Cfr. Section 3 Fortran 2008 Standard].
If you want to add it to your output, you have to create a
character of the requested kind that represents that particular
character. To do this, you make use of ACHAR(I [, KIND]) which
converts the ASCII code I into that particular character of kind
KIND or the default kind if KIND is not specified. For the
<tab>-character this would read:
ACHAR(9)
Another way, but less preferred, would be to make use of the
ISO_C_BINDING module which defines the constant
C_HORIZNTAL_TAB. This represents \t, a character of the
C-character kind C_CHAR. If C_CHAR=-1, the constant is converted
to ACHAR(9) [Cfr. Section 15.2 Fortran 2008 Standard]
See Vladimir's answer for the howto.
I have a project written in VS2010 with Intel Visual Fortran. I have a dump subroutine to write a 2D matrix into file:
subroutine Dump2D(Name,Nx,Ny,Res)
implicit none
integer i,j,Nx,Ny
real(8) :: Res(Nx,Ny)
character(len=30) name,Filename
logical alive
write(filename,*) trim(Name),".dat"
Write(*,*) "Saving ",trim(Name)," Please wait..."
open (10,file=filename)
do i=1,Ny
Write(10,FMt="(D21.13\)") (Res(j,i),j=1,Nx)
Write(10,*)
end do
close(10)
Write(*,*) "Save ",trim(Name),"Complete!"
return
end subroutine Dump2D
It is ok to compile and run. But when I compile in emacs using gfortran it gives me the error:
I think it's because the gfortran doesn't recognize \ in a format for a write command. How do I fix this problem?
Write(10,FMt="(D21.13\)") (Res(j,i),j=1,Nx)
1
Error: Unexpected element '\' in format string at (1)
The edit descriptor \ relates to backslash editing. This is a non-standard extension provided by the Intel compiler (and perhaps others). It is not supported by gfortran.
Such backslash editing is intended to affect carriage control. Much as in this answer such an effect can be handled with the (standard) non-advancing output.1
As you simply want to output each column of a matrix to a record/line you needn't bother with this effort.2 Instead (as you'll see in many other questions):
do i=1,Ny
write(10,fmt="(*(D21.13))") Res(:,i)
end do
There are also other approaches which a more general search will find.
1 The Intel compiler treats \ and $ in the same way.
2 There are subtle aspects of \, but I'll assume you don't care about those.
Another approach (although francescalus answer is better in your case) would be to build a format string that contains the number of elements to include in your row. One way of doing this is to use the following to build the format string (which uses an explicit space character to separate elements within a line in the file):
WRITE(fmtString, '(A,I0,A)') '(', Nx, '(D21.13,:,1X))' *
Then use the format string variable in your WRITE statement as so:
do i=1,Ny
Write(10,FMt=fmtString) (Res(j,i),j=1,Nx)
end do
This approach can also be very useful if you want to use something other than spaces to separate elements (e.g. commas or semicolons).
*As that's a little difficult to read, I will provide an example. For Nx = 3, this would be equivalent to:
fmtString = '(3(D21.13,:,1X))'
Which is 2 numbers formatted using D21.13, each followed by a space, and a final number formatted using D21.13, but without a space after it (as the ":" stops at the final item).
The backslash is not valid in Fortran 77 FORMAT statements. Gfortran will not compile it, unless you fix the code. There is no flag that will change that AFAIK (-fbackslash should not help here).
If I understand the intention correctly (and I may be wrong), the backslash does the same as the dollar sign in some other compilers and prevents terminating a record (line). In that case the advance="no" put in the write statement should help. It is Fortran 90, but you should not avoid it just for that reason.
I have a project written in VS2010 with Intel Visual Fortran. I have a dump subroutine to write a 2D matrix into file:
subroutine Dump2D(Name,Nx,Ny,Res)
implicit none
integer i,j,Nx,Ny
real(8) :: Res(Nx,Ny)
character(len=30) name,Filename
logical alive
write(filename,*) trim(Name),".dat"
Write(*,*) "Saving ",trim(Name)," Please wait..."
open (10,file=filename)
do i=1,Ny
Write(10,FMt="(D21.13\)") (Res(j,i),j=1,Nx)
Write(10,*)
end do
close(10)
Write(*,*) "Save ",trim(Name),"Complete!"
return
end subroutine Dump2D
It is ok to compile and run. But when I compile in emacs using gfortran it gives me the error:
I think it's because the gfortran doesn't recognize \ in a format for a write command. How do I fix this problem?
Write(10,FMt="(D21.13\)") (Res(j,i),j=1,Nx)
1
Error: Unexpected element '\' in format string at (1)
The edit descriptor \ relates to backslash editing. This is a non-standard extension provided by the Intel compiler (and perhaps others). It is not supported by gfortran.
Such backslash editing is intended to affect carriage control. Much as in this answer such an effect can be handled with the (standard) non-advancing output.1
As you simply want to output each column of a matrix to a record/line you needn't bother with this effort.2 Instead (as you'll see in many other questions):
do i=1,Ny
write(10,fmt="(*(D21.13))") Res(:,i)
end do
There are also other approaches which a more general search will find.
1 The Intel compiler treats \ and $ in the same way.
2 There are subtle aspects of \, but I'll assume you don't care about those.
Another approach (although francescalus answer is better in your case) would be to build a format string that contains the number of elements to include in your row. One way of doing this is to use the following to build the format string (which uses an explicit space character to separate elements within a line in the file):
WRITE(fmtString, '(A,I0,A)') '(', Nx, '(D21.13,:,1X))' *
Then use the format string variable in your WRITE statement as so:
do i=1,Ny
Write(10,FMt=fmtString) (Res(j,i),j=1,Nx)
end do
This approach can also be very useful if you want to use something other than spaces to separate elements (e.g. commas or semicolons).
*As that's a little difficult to read, I will provide an example. For Nx = 3, this would be equivalent to:
fmtString = '(3(D21.13,:,1X))'
Which is 2 numbers formatted using D21.13, each followed by a space, and a final number formatted using D21.13, but without a space after it (as the ":" stops at the final item).
The backslash is not valid in Fortran 77 FORMAT statements. Gfortran will not compile it, unless you fix the code. There is no flag that will change that AFAIK (-fbackslash should not help here).
If I understand the intention correctly (and I may be wrong), the backslash does the same as the dollar sign in some other compilers and prevents terminating a record (line). In that case the advance="no" put in the write statement should help. It is Fortran 90, but you should not avoid it just for that reason.
Is it Fortran-standard compliant to read a tabs-delimited Ascii file like this one:
0.11 0.12 0.45
(where the space is actually a tab) with list-directed input like this:
read(11,*) real1,real2,real3
A more interesting question than a first glance might suggest ...
The standard stipulates that blanks are to be recognised as value separators for list-directed input. In Table 3.1 'Special Characters' of (my version of the draft of) the standard a space is denoted Blank character, but there is no further explanation or definition of blank. So a space is definitely a blank inside the source of a Fortran program.
It is well known (??) that the tab character is not part of the Fortran character set, and some compilers will, by default, object to its presence in source files (outside character variable contexts). But I can't see any anyone writing a compiler that would fail to recognise a tab character as a blank for list-directed input of a list of numbers.
I think the answer to the question is
Whether or not a tab character is a value separator for an input list
is processor dependent (i.e. it's left up to the compiler writer) so the standard doesn't stipulate that you can absolutely rely on this behaviour.
but I'll be interested to see what the language lawyers have to contribute on this one.
I'm attempting to modernize an old code (or at least make it a bit more understandable) but I've run into an odd format for a, uh, FORMAT statement.
Specifically, it's a FORMAT statement with Hollerith constants in it (the nH where n is a number):
FORMAT(15H ((C(I,J),J=1,I3,12H),(D(J),J=1,I3, 6H),I=1,I3,') te'
1,'xt' )
This messes with the syntax highlighting as it appears this has unclosed parenthesis. It compiles fine with this format statement as is, but closing the parenthesis causes a compiling error (using either the intel or gfortran compiler).
As I understand it, Hollerith constants were a creature of Fortran 66 and were replaced with the advent of the CHARACTERin Fortran 77. I generally understand them when used as something like a character, but use as a FORMAT confuses me.
Further, if I change 15H ((... to 15H ((... (i.e. I remove one space) it won't compile. In fact, it won't compile even if I change the code to this:
FORMAT(15H ((C(I,J),J=1,I3,12H),(D(J),J=1,I3, 6H),I=1,I3,') text' )
I would like this to instead be in a more normal (F77+) format. Any help is appreciated.
What you have are actually Hollerith edit descriptors, not constants (which would occur in a DATA or CALL statement), although they use the same syntax. F77 replaced Hollerith constants outright; it added char-literal edit descriptor as a (much!) better alternative, but H edit descriptor remained in the standard until F95 (and even then some compilers still accepted it as a compatibility feature).
In any case, the number before the H takes that number of characters after the H, without any other delimiter; that's why deleting (or adding) a character after the H screws it up. Parsing your format breaks it into these pieces
15H ((C(I,J),J=1,
I3,
12H),(D(J),J=1,
I3,
6H),I=1,
I3,
') te'
'xt'
and thus a modern equivalent (with optional spaces for clarity) is
nn FORMAT( ' ((C(I,J),J=1,', I3, '),(D(J),J=1,', I3, '),I=1,', I3
1,') text' )
or if you prefer you can put that text after continuation (including the parens) in a CHARACTER value, variable or parameter, used in the I/O statement instead of a FORMAT label, but since you must double all the quote characters to get them in a CHARACTER value that's less convenient.
Your all-on-one-line version probably didn't compile because you were using fixed-form, perhaps by default, and only the first 72 characters of each source line are accepted in fixed-form, of which the first 6 are reserved for statement number and continuation indicator, leaving only 66 and that statement is 71 by my count. Practically any compiler you will find today also accepts free-form, which allows longer lines and has other advantages too for new code, but may require changes in existing code, sometimes extensive changes.