I am transfering an integer to a string using the following method
Character (len=10) :: s
Integer :: i
i = 7
Write (s, *, iostat=ios) i
However this leaves the contents of s empty. When I introduce an explicit format, s is populated as intended.
Character (len=10) :: s
Integer :: i
i = 7
Write (s, "(i3)", iostat=ios) i
It looks like the problem is related to the length of the string s because
when I use a longer length, I do get the correct number.
Character (len=25) :: s
The first lesson to take from this is: if you use the iostat= specifier, check the result. However, the behaviour of your code is seemingly not guaranteed. I'll base this part of the answer on intepreting how your compiler is taking things.
In addition to the iostat= specifier, in general you can use, as Vladimir F mentions in a comment, the iomsg= specifier to get a friendly message. [As IanH notes, the nominated variable is updated, and in particular may otherwise remain undefined, only in situations where the variable for the iostat= specifier is (or would be) set to non-zero.]
character (len=10) s
character (len=58) mesg
integer ios
write(s,*, iostat=ios, iomsg=mesg) 7
if (ios/=0) print*, ios, TRIM(mesg)
You want to check this, because you are using list-directed output. Here, the compiler is free to choose "reasonable" values for the integer edit format. It's more than likely that, for default integer kind, the field would be longer than 9 (don't forget the leading blank). Thus, it doesn't "fit" into the length-10 character record: "End of record" would be reasonable for mesg in this case.
With the explicit format I3 it fits with much to spare.
Why you see LEN_TRIM(s) as 10, is that s actually likely becomes junk.
Now, coming to the final part. It appears that your code with list-directed output is not valid. Fortran 2008 (and I presume many others) explicitly states:
On output, the output list and format specification shall not specify more characters for a record than ... the record length of an internal file.
The record length of your internal file being 10.
The usual caveats of relying on any particular behaviour hold. I'd be disappointed, though, if something dramatic happened.
Related
This question has been covered somewhat in previous SO questions. However, previous discussions seem somewhat incomplete.
Fortran has several I/O statements. There is READ(*,*) and WRITE(*,*), etc. The first asterisk (*) is the standard asterisk designating an input or output from the keyboard to/from the screen. My question is about the second asterisk:
The second asterisk designates the format of the I/O elements, the data TYPE which is being used. If this asterisk is left unchanged, the fortran complier uses the default format (whatever that may be, based on the compiler). Users must use a number of format descriptors to designate the data type, precision, and so forth.
(1) Are these format descriptors universal for all Fortran compilers and for all versions of Fortran?
(2) Where can I find the standard list of these format descriptors? For example, F8.3 means that the number should be printed using fixed point notation with field width 8 and 3 decimal places.
EDIT: A reference for edit descriptors can be found here: http://fortranwiki.org/fortran/show/Edit+descriptors
First, as a clarification, the 1st asterisk in the READ/WRITE statement has a slightly different meaning than you state. For write, it means write to the default file unit (in linux world generally standard out), for read it means read from the default file unit (in linux world generally standard in), either of which may not necessarily be connected to a terminal screen or a keyboard.
The 2nd asterisk means use list directed IO. For read statements this is generally useful because you don't need a specified format for your input. It breaks up the line into fields separated by space or comma (maybe a couple others that aren't commonly used), and reads each field in turn into the variable associated with that field in the argument list, ignoring unread fields, and continuing onto the next line if not enough fields were read in (unless a line termination character \ is explicitly included).
For writes, it means the compiler is allowed to determine what format to write the variables out (I believe with no separator). I believe it is allowed to do this at run time, so that you are all but guaranteed that the value it is trying to write will fit into the format specifier used, so you can be assured that you won't get ******* written out. The down side is you have to manually include a separator character in your argument list, or all your numbers will run together.
In general, using list directed read is more of a convenience to the user, so they don't have to fit their inputs into rigidly defined fields, and list directed writes are a convenience to the programmer, in case they're not sure what the output will look like.
When you have a data transfer statement like read(*,*) ... it's helpful to understand exactly what this means. read(*,*) is equivalent to the more verbose read(unit=*, fmt=*). This second asterisk, as you have it, makes this read statement (or corresponding write statement) list-directed.
List-directed input/output, as described elsewhere, is a convenience for the programmer. The Fortran standards specify lots of constraints that the compiler must follow, but this language has things like "reasonable values", so allowing output to vary by compiler, settings, and so on.
Again, as described elsewhere, fine user control over the output (or input) comes with giving a format specification. Instead of read(*,fmt=*), something like read(*,fmt=1014) or read(*,fmt=format_variable_or_literal). I take it your question is: what is this format specification?
I won't go into details of all of the possible edit descriptors, but I will say in response to (2): you can find the list of those edit descriptors in the Fortran standard (Clause 10 of Fortran 2008 goes into all the detail) or a good reference book.
To answer (1): no, edit descriptors are not universal. Even across Fortran standards. Of note are:
The introduction of I0 (and other minimal-width specifiers) for output in Fortran 95;
The removal of the H edit descriptor in Fortran 95;
The introduction of the DT edit descriptor in Fortran 2003.
I tried to assign the horizontal table
character*(*) argz(*),tab*1
data tab /Z'09'/
Compiling with both f77 and gfortran gave
data tab /Z'09'/
1 Error: Incompatible types in DATA statement at (1); attempted conversion of INTEGER(16) to CHARACTER(1)
As commented, if you simply want an ASCII tab character then ACHAR(9) provides such a thing. However, there are other aspects to this question which makes it much more general.
A literal constant such as Z'09' is known as a BOZ constant. This represents a series of bits.
Use of a BOZ constant is quite restricted in the Fortran standards (becoming less so over time) and many compilers allow other uses beyond the standard as extensions. For example, a BOZ constant in a Fortran-compliant program may appear in only a small number of places. Some compilers may allow them to appear any way a literal constant may.
The Oracle documentation you point to in a comment even has that compiler allowing the type of the expression assumed from its use.
With your compilers, trying
character tab
data tab /Z'09'/
fails. The gfortran message says that it is taking the constant to be of type integer(16) which (correctly) cannot be converted to character. Further, according to the Fortran standard, any data object defined by a BOZ constant in a data statement must be an integer.
We know that
character :: tab=ACHAR(9) ! This is also explicit initialization.
has the desired effect, but can we do this with a BOZ constant?
You point to the gfortran documentation of achar and say that it doesn't refer to the argument being hexadecimal. It says there that I must be integer. A BOZ constant isn't an integer, so achar(Z'09') isn't allowed by Fortran. [Although this is actually accepted by gfortran and other compilers.]
A fully standard compliant approach is
character :: tab=ACHAR(INT(Z'09'))
as int accepts these constants, returning an integer (which is in turn acceptable to achar).
The constant expression achar(int(z'09')) may not itself appear in a data statement like
character tab
data tab /ACHAR(INT(Z'09'))/ ! No...
as it isn't a constant. However, we could have
character, parameter :: tabconst=ACHAR(INT(Z'09'))
character tab
data tab /tabconst/ ! tabconst is a (named) constant
I am learning Fortran because well, yeah, thought I'd learn it. However, I've found utterly no information on what the purpose of * is in print, read, etc:
program main
print *, "Hello, world!"
end program main
What is the purpose of this *? I've done some research however I don't think I understand it properly, I don't want to carry on learning until I actually know the point of *.
From what I've managed to find I think that it's some sort of format specifier, however, I don't understand what that means and I have no idea if I'm even correct. All the tutorials I've found just tell me what to write to print to the console but not what * actually means.
You are correct in that it is a format specifier.
There's a page on Wikibooks to do with IO and that states:
The second * specifies the format the user wants the number read with
when talking about the read statement. This applies to the write and print statements too.
For fixed point reals: Fw.d; w is the total number of spaces alloted for the number, and d is the number of decimal places.
And the example they give is
REAL :: A
READ(*,'(F5.2)') A
which reads a real number with 2 digits before and after the decimal point. So if you were printing a real number you'd use:
PRINT '(F5.2)', A
to get the rounded output.
In your example you're just printing text so there's no special formatting to do. Also if you leave the format specifier as * it will apply the default formatting to reals etc.
The print statement does formatted output to a special place (which we assume is the screen). There are three available ways to specify the format used in this output. One of these, as in the question, is using *.
The * format specifier means that the formatted output will be so-called list-directed output. Conversely, for a read statement, it will be list-directed input. Now that the term has been introduced you will be able to find many other questions here: list-directed input/output has many potentially surprising consequences.
Generally, a format specification item says how to format an item in the input/output list. If we are writing out a real number we'd use a format item which may, say, state the precision of the output or whether it uses scientific notation.
As in the question, when writing out a character variable we may want to specify the width of the output field (so that there is blank padding, or partial output) or not. We could have
print '(A20)', "Hello, world!"
print '(A5)', "Hello, world!"
print '(A)', "Hello, world!"
which offers a selection of effects. [Using a literal character constant like '(A)' is one of the other ways of giving the format.]
But we couldn't have
print '(F12.5)', "Hello, world!" ! A numeric format for a character variable
as our format doesn't make sense with the output item.
List-directed output is different from the above cases. Instead, (quote here and later from the Fortran 2008 draft standard) this
allows data editing according to the type of the list item instead of by a format specification. It also allows data to be free-field, that is, separated by commas (or semicolons) or blanks.
The main effect, and why list-directed is such a convenience, is that no effort is required on the part of the programmer to craft a suitable format for the things to be sent out.
When an output list is processed under list-directed output and a real value appears it is as though the programmer gave a suitable format for that value. And the same for other types.
But the crucial thing here is "a suitable format". The end user doesn't get to say A5 or F12.5. Instead of that latter the compiler gets to choose "reasonable processor-dependent values" for widths, precisions and so on. [Leading to questions like "why so much white space?".] The constraints on the output are given in, for example, Fortran 2008 10.10.4.
So, in summary * is saying, print out the following things in a reasonable way. I won't complain how you choose to do this, even if you give me output like
5*0
1 2
rather than
0 0 0 0 0 1 2
and I certainly won't complain about having a leading space like
Hello, world!
rather than
Hello, world!
For, yes, with list-directed you will (except in cases beyond this answer) get an initial blank on the output:
Except for new records created by [a special case] or by continuation of delimited character sequences, each output record begins with a blank character.
This question has been covered somewhat in previous SO questions. However, previous discussions seem somewhat incomplete.
Fortran has several I/O statements. There is READ(*,*) and WRITE(*,*), etc. The first asterisk (*) is the standard asterisk designating an input or output from the keyboard to/from the screen. My question is about the second asterisk:
The second asterisk designates the format of the I/O elements, the data TYPE which is being used. If this asterisk is left unchanged, the fortran complier uses the default format (whatever that may be, based on the compiler). Users must use a number of format descriptors to designate the data type, precision, and so forth.
(1) Are these format descriptors universal for all Fortran compilers and for all versions of Fortran?
(2) Where can I find the standard list of these format descriptors? For example, F8.3 means that the number should be printed using fixed point notation with field width 8 and 3 decimal places.
EDIT: A reference for edit descriptors can be found here: http://fortranwiki.org/fortran/show/Edit+descriptors
First, as a clarification, the 1st asterisk in the READ/WRITE statement has a slightly different meaning than you state. For write, it means write to the default file unit (in linux world generally standard out), for read it means read from the default file unit (in linux world generally standard in), either of which may not necessarily be connected to a terminal screen or a keyboard.
The 2nd asterisk means use list directed IO. For read statements this is generally useful because you don't need a specified format for your input. It breaks up the line into fields separated by space or comma (maybe a couple others that aren't commonly used), and reads each field in turn into the variable associated with that field in the argument list, ignoring unread fields, and continuing onto the next line if not enough fields were read in (unless a line termination character \ is explicitly included).
For writes, it means the compiler is allowed to determine what format to write the variables out (I believe with no separator). I believe it is allowed to do this at run time, so that you are all but guaranteed that the value it is trying to write will fit into the format specifier used, so you can be assured that you won't get ******* written out. The down side is you have to manually include a separator character in your argument list, or all your numbers will run together.
In general, using list directed read is more of a convenience to the user, so they don't have to fit their inputs into rigidly defined fields, and list directed writes are a convenience to the programmer, in case they're not sure what the output will look like.
When you have a data transfer statement like read(*,*) ... it's helpful to understand exactly what this means. read(*,*) is equivalent to the more verbose read(unit=*, fmt=*). This second asterisk, as you have it, makes this read statement (or corresponding write statement) list-directed.
List-directed input/output, as described elsewhere, is a convenience for the programmer. The Fortran standards specify lots of constraints that the compiler must follow, but this language has things like "reasonable values", so allowing output to vary by compiler, settings, and so on.
Again, as described elsewhere, fine user control over the output (or input) comes with giving a format specification. Instead of read(*,fmt=*), something like read(*,fmt=1014) or read(*,fmt=format_variable_or_literal). I take it your question is: what is this format specification?
I won't go into details of all of the possible edit descriptors, but I will say in response to (2): you can find the list of those edit descriptors in the Fortran standard (Clause 10 of Fortran 2008 goes into all the detail) or a good reference book.
To answer (1): no, edit descriptors are not universal. Even across Fortran standards. Of note are:
The introduction of I0 (and other minimal-width specifiers) for output in Fortran 95;
The removal of the H edit descriptor in Fortran 95;
The introduction of the DT edit descriptor in Fortran 2003.
Can I specify a format specifier for a complex number in fortran? I have a simple program.
program complx1
implicit none
complex :: var1
var1 = (10,20)
write (*,*) var1
write (*,'(F0.0)') var1
write (*,'(F0.0,A,F0.0)') real(var1), ' + i ' , aimag(var1)
end program complx1
Output:
( 10.0000000 , 20.0000000 )
10.
20.
10. + i 20.
I wanted to use inbuilt format for a+bi with some format specifier, instead of one did manually (second last line of program). Obviously F0.0 did not work. Any ideas?
EDIT:
I don't think this is a duplicate of post: writing complex matrix in fortran, which says to use REAL and AIMAG functions. I already used those functions and wondering whether there is an inbuilt format that can do the work.
An addendum to #francescalus' existing, and mostly satisfactory, answer. A format string such as
fmt = '(F0.0,SP,F0.0,"i")'
should result in a complex number being displayed with the correct sign between real and imaginary parts; no need to fiddle around with strings to get a plus sign in there.
There is no distinct complex edit descriptor. In Fortran 2008, 10.7.2.3.6 we see
A complex datum consists of a pair of separate real data. The editing of a scalar datum of complex type is specified by two edit descriptors each of which specifies the editing of real data.
In your second example, which you say "did not work", you see this formatting in action. Because the format had only one descriptor with no repeat count the values are output in distinct records (format reversion).
The first of your three cases is a very special one: it uses list-directed output. The rules for the output are
Complex constants are enclosed in parentheses with a separator between the real and imaginary parts
There is another useful part of the first rule mentioned:
Control and character string edit descriptors may be processed between the edit descriptor for the real part and the edit descriptor for the imaginary part.
You could happily adapt your second attempt, as we note that your "not working" wasn't because of the use of the complex variable itself (rather than the real and imaginary components)
write (*, '(F0.0,"+i",F0.0)') var1
This, though, isn't right when you have potentially negative complex part. You'll need to change the sign in the middle. This is possible, using a character variable format (rather than literal) with a conditional, but it perhaps isn't worth the effort. See another answer for details of another approach, similar to your third option but more robust.
Another option is to write a function which returns a correctly written character representation of your complex variable. That's like your third option. It is also the least messy approach when you want to write out many complex variables.
Finally, if you do have to worry about negative complex parts but want a simple specification of the variable list, there is the truly ugly
write(*,'(F0.0,"+i*(",F0.0,")")') var1
or the imaginative
character(19) fmt
fmt = '(F0.0,"+",F0.0,"i")'
fmt(8:8) = MERGE('+',' ',var1%im.gt.0)
write(*,fmt) var1
or the even better use of the SP control edit descriptor as given by High Performance Mark's answer which temporarily (for the duration of the output statement) sets the sign mode of the transfer to PLUS which forces the printing of the otherwise optional "+" sign. [Alternatively, this can be set for the connection itself in an open with the sign='plus' specifier.]
All this is because the simple answer is: no, there is no in-built complex edit descriptor.