Home > Archive > Fortran > October 2004 > ASCII and BINARY Write()
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
ASCII and BINARY Write()
|
|
| Ron G. 2004-10-19, 3:58 pm |
| Hi,
I have several hundred binary WRITE statements in the form
WRITE(IUNIT)A,B,C,D. For debugging, I would like to write these in
ASCII. I know I can do this with an IF statement:
IF(doASCII) THEN
WRITE(IUNIT,*)A,B,C,D
ELSE
WRITE(IUNIT)A,B,C,D
ENDIF
but this requires recoding every single WRITE statement.
It seems that there should be a way to do something like this at the
top of the file...
IF(doASCII)THEN
IO_CONTROL_STRING = "*"
ELSE
IO_CONTROL_STRING = " "
ENDIF
and then simply add the control string to the WRITE...
WRITE(IUNIT,IO_CONTROL_STRING)A,B,C,D
Unfortunately, the above does not work. Is there any way to
incorporate a variable IO control string in a WRITE statement?
Thanks,
Ron
| |
| Arjen Markus 2004-10-19, 3:58 pm |
| "Ron G." wrote:
>
> Hi,
>
> I have several hundred binary WRITE statements in the form
> WRITE(IUNIT)A,B,C,D. For debugging, I would like to write these in
> ASCII. I know I can do this with an IF statement:
>
> IF(doASCII) THEN
> WRITE(IUNIT,*)A,B,C,D
> ELSE
> WRITE(IUNIT)A,B,C,D
> ENDIF
>
> but this requires recoding every single WRITE statement.
>
> It seems that there should be a way to do something like this at the
> top of the file...
>
> IF(doASCII)THEN
> IO_CONTROL_STRING = "*"
> ELSE
> IO_CONTROL_STRING = " "
> ENDIF
>
> and then simply add the control string to the WRITE...
> WRITE(IUNIT,IO_CONTROL_STRING)A,B,C,D
>
> Unfortunately, the above does not work. Is there any way to
> incorporate a variable IO control string in a WRITE statement?
>
> Thanks,
> Ron
As far as I know, there is none. The reason is, if I understand such
matters correctly, that writing to a formatted file is a completely
different process than writing to an unformatted file, even though
the _textual_ change to your source code seems minimal.
Because of these completely different processes a runtime switch
like the one you are looking for is simply impossible.
Regards,
Arjen
| |
| Richard E Maine 2004-10-19, 3:58 pm |
| rgiordano@petrotel.com (Ron G.) writes:
> IF(doASCII) THEN
> WRITE(IUNIT,*)A,B,C,D
> ELSE
> WRITE(IUNIT)A,B,C,D
> ENDIF
>
> but this requires recoding every single WRITE statement.
It also requires changing the OPEN statement... assuming that you are
using an OPEN statement, which I strongly recommend. And if you were
doing anything other than the most trivial, there could be all kinds of
other repercussions. For example, you could end up with different numbers
records because formatted writes sometimes write multiple records.
This is a significant enough change, that I'd worry pretty seriously
about it introducing Heisenbergs (looking for the bug makes its
symptoms change or even disappear).
All in all, I'd think this has a fair chance of introducing more bugs
than it is likely to help you find. The bigger and more complicated
the program gets, the more I'd worry about this introducing
problems. Have you considered just something like a filedump utility
to help you look at the unformatted file? Admitedly, such utilities
can be a bit of a pain, but they don't require such surgery to the
code youu are trying to debug.
> It seems that there should be a way to do something like this at the
> top of the file...
>
> IF(doASCII)THEN
> IO_CONTROL_STRING = "*"
> ELSE
> IO_CONTROL_STRING = " "
> ENDIF
>
> and then simply add the control string to the WRITE...
> WRITE(IUNIT,IO_CONTROL_STRING)A,B,C,D
>
> Unfortunately, the above does not work.
Among other things, the above write is *EXACTLY* the correct syntax
for a write with an explicit format. The variable name IO_CONTROL_STRING
is a little strange, but the standard doesn't require sensible names.
And those 2 values aren't good explicit formats (something like '(4g20.10)'
would fit better), but the compiler can't necessarily see the variable
value at compile time.
> Is there any way to
> incorporate a variable IO control string in a WRITE statement?
Sorry, no. You can have variable values for the various IO specifiers,
but you can't use a variable to change what IO specifiers are in the
statement. In this case, you are trying to change whether the statement
has a FMT specifier or not. Changing the value of the FMT specifier to a
blank string isn't the same as not having the specifier.
There are some things you can specify with variables, but other more
fundamental things need to be specified at compile time. Whether the
I/O is formatted or unformatted is one of those pretty fundamental
things. Formatted I/O tends to be pretty dramatically different
from unformatted. I'm not saying that it couldn't be done with a
variable; clearly it could. One could do all I/O with an interpreter.
This just happens to be past the boundary of what the standard allows
to be run-time changeable.
I note as an aside, that run-time variability is one of the advantages
of the f90 standard way of specifying access= with a variable value
instead of using multiple specifiers (such as readonly) as done in
some f77 extensions. With the multiple specifiers, one had to use IF
constructs and multiple OPEN statements in order to write an OPEN that
could be used both with and without readonly.
Other than using a filedump utility, other possible approaches to your
problem include:
1. You could use a macro pre-processor. This would be an absolutely
trivial application of such a thing. It isn't part of the Fortran
standard, but macro pre-processors are easy enough to find. Heck,
it wouldn't take very long to write one from scratch in Fortran to
do this one trivial case... but I wouldn't really suggest writing
your own anyway.
2. Staying within Fortran, you could modularize the writes so that they
were all done in a subroutine, or maybe a small set of them. Then
you'd just have to change the one (or few) subroutine(s).
This does have the problem that it rapidly grows in complexity if
you have many different variants of I/O lists, because you'd need a
different subroutine (or optional arguments) for every argument
list that had a different number of items or different type, kind,
or rank for an item. This could vary from one case for the whole
program to one case for every write statement.
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
| |
| glen herrmannsfeldt 2004-10-19, 3:58 pm |
|
Ron G. wrote:
> I have several hundred binary WRITE statements in the form
> WRITE(IUNIT)A,B,C,D. For debugging, I would like to write these in
> ASCII. I know I can do this with an IF statement:
> IF(doASCII) THEN
> WRITE(IUNIT,*)A,B,C,D
> ELSE
> WRITE(IUNIT)A,B,C,D
> ENDIF
When I have had this problem I would write a simple program
that reads the binary file and writes a text file.
(It wasn't always ASCII though.)
This also helps to verify that the binary file format is
consistent, comes in handy when debugging after having
written the binary file, and is a good start toward the
program that will eventually read that file.
For one I did, each record of the file could be read by:
READ(1) I,L,A,B,C,D,(X(J),J=1,L),(Y(J),J=1,L)
I indicated the record type, L the length of the arrays,
A,B,C,D,X,Y were all REAL variables.
-- glen
| |
| Paul Van Delst 2004-10-19, 3:58 pm |
| Richard E Maine wrote:
> rgiordano@petrotel.com (Ron G.) writes:
>
>
>
>
[snip]
> Have you considered just something like a filedump utility
> to help you look at the unformatted file? Admitedly, such utilities
> can be a bit of a pain, but they don't require such surgery to the
> code youu are trying to debug.
I was going to suggest something along those lines also. Before I switched unformatted
file writing from "regular" Fortran to using the netCDF API, that's what I did. I'd run
the code and then dump the contents with my dump program. The only thing that has changed
is that netCDF comes with its own filedump app, ncdump. For me it's the same dog, just a
different leg.
And, if it was possible to do what the OP asked, and the debugging is successful with the
ASCII o/p option, wouldn't you then have to rerun the same case but with a "doBinary" just
to get exactly the same output in the required/production non-ASCII format?
cheers,
paulv
| |
| Ron G. 2004-10-20, 8:57 pm |
| All,
Thank you for your suggestions and words of wisdom. They are very helpful.
Regards,
RonG
|
|
|
|
|