0

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
6
  • Do you check the value of ios in the first case? What do you get for LEN_TRIM(s) in the second? [I guess it's greater than 10.] Commented Dec 13, 2014 at 20:22
  • ios is -2 when using fmt=*, len_trim(s) is 10 Commented Dec 13, 2014 at 20:32
  • So just use iomsg too and read why it fails. Commented Dec 13, 2014 at 20:32
  • ios is 0 when using fmt="(i3)", and len_trim(s) is 3 Commented Dec 13, 2014 at 20:33
  • ios = -2 means End of record Commented Dec 13, 2014 at 20:35

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Be mindful that the definition status of the variable nominated by the iomsg specifier is not changed if the value of the variable set by the iostat specifier is zero.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.