From: Dave Allured on
Bart Vandewoestyne wrote:
>
> On 2009-09-15, Arjen Markus <arjen.markus895(a)gmail.com> wrote:
> >
> > You can read the line in a single string and then
> > split it into the two items:
> >
> > integer :: ivalue
> > character(len=100) :: line, keyword
> >
> > read( 10, '(a)' ) line
> > !
> > ! Identify the keyword and thus the type of data
> > !
> > read( line, * ) keyword
> >
> > if ( keyword == "nb_apples" ) then
> > !
> > ! Integer value ...
> > !
> > read( line, * ) keyword, ivalue
> > endif
> >
> > ! And so on
> >
> >
> > Regards,
> >
> > Arjen
>
> Thanks Arjen.
>
> In the meanwhile, I was able to program myself my own
> proof of concept:
>
> program config_reader
>
> character(len=20) :: variable_name
> character(len=20) :: variable_value
>
> character(len=20) :: name
> integer :: nb_apples
> real :: my_weight, elephant_weight
> logical :: smoking_allowed
> integer :: mysize
>
> open(unit=1, file="test.dat", action="read")
> do
> read(unit=1, fmt=*, iostat=ios) variable_name, variable_value
> if (ios /= 0) then
> exit
> end if
>
> if (variable_name == "nb_apples") then
> read(variable_value, fmt=*) nb_apples
> print *, "nb_apples = ", nb_apples
> end if
> if (variable_name == "my_weight") then
> read(variable_value, fmt=*) my_weight
> print *, "my_weight = ", my_weight
> end if
> if (variable_name == "elephant_weight") then
> read(variable_value, fmt=*) elephant_weight
> print *, "elephant_weight = ", elephant_weight
> end if
> if (variable_name == "smoking_allowed") then
> read(variable_value, fmt=*) smoking_allowed
> print *, "smoking_allowed = ", smoking_allowed
> end if
>
> end do
>
> end program config_reader
>
> It seems like I'm doing it similar as you, but if anybody things this
> is a bad approach and has an even more elegant solution, i would be happy
> to hear!

I have run into at least one compiler that did not do what you expect
with this (standards notwithstanding):

read(unit=1, fmt=*, iostat=ios) variable_name, variable_value

If you are interested in portability, then do the original read with
formatted input rather than list-directed input:

read(unit=1, fmt='(a16,a)', iostat=ios) variable_name, &
variable_value

Or maybe this, closer to Arjen's suggestion:

character line*100
...
read(unit=1, fmt='(a)', iostat=ios) line
variable_name = line(1:16)
variable_value = line(17:)

Both have the added advantage that you can reliably read strings with
embedded blanks and punctuation, with no extra effort.

If you decide you would like free form input rather than fixed width, it
is easy to extend the latter to parse out either an explicit delimiter
character e.g. ":" or a set of consecutive blanks as the separater
between "name" and "value".

--Dave
From: nmm1 on
In article <1j62v8a.1pkc2vc1s3xt84N%nospam(a)see.signature>,
Richard Maine <nospam(a)see.signature> wrote:
>
>Oddly, I largely stopped using namelist right about when it became
>standardized. It wasn't so much because I particularly disaprove of
>namelist as it was a combination of two things.

I rarely used it, except for temporary testing code. Curiously,
in my first Fortran program, I wrote a NAMELIST-like facility, as
I needed to test bizarre combinations of data.

>1. I wanted more flexibility than namelist gives. I'll not go into
>details here, as there are just so many ways in which roll-your-own is
>more flexible than namelist.
>
>2. Sometime around then, I built a personal library of procedures that
>facilitated rolling my own input parsing. This was nothing particularly
>fancy or esoteric - mostly just routines to do the kinds of things that
>always come up: read a "command" handling a line continuation
>convention, extract the next field using blanks or other field
>delimiters, convert a string to a real or integer with error checking,
>etc.

Yes. I think that Fortran needs such a facility, but it would clearly
be a case for a TR, and would need someone to produce a decent proposal
in the first place. It might be better just to remove the unnecessary
restrictions from I/O, which would get most of the way there.


Regards,
Nick Maclaren.
From: Richard Maine on
Dave Allured <nospom(a)indra.com> wrote:

> I have run into at least one compiler that did not do what you expect
> with this (standards notwithstanding):
>
> read(unit=1, fmt=*, iostat=ios) variable_name, variable_value

I have not, and I've used this kind of thing on more compilers than can
easily be counted, even since it was introduced in f77. It would be
helpful if you would specify exactly what *DID* happen instead of just
that it "did not do what you expect". My guess is that your expectations
ran contrary to the standard, but there is no way I can verify that from
the information given. I cannot agree to recommendations based on a
single vague and unverified claim.

For example, if the value has any special characters (a / as often found
in pathnames is one example), the result might surprise you, but that
would be in accordance with the standard.

There are lots of other possibilities that might surprise you, but are
still in accordance with the standard. I don't think I'll try to list
them all.

> If you are interested in portability, then do the original read with
> formatted input rather than list-directed input:

I'll give my knee-jerk reaction to this common error. List-directed
input is a form of formatted input. In fact, the long-winded term is
"list-directed formatting", although you mostly won't see people being
quite that verbose outside of the standard. What you are referring to is
explicit formatting as opposed to list-directed formating. Yes,
programming errors do result from this terminology error, so it is more
than just a pointless nitpick.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: Dave Allured on
Richard Maine wrote:
>
> Dave Allured <nospom(a)indra.com> wrote:
>
> > I have run into at least one compiler that did not do what you expect
> > with this (standards notwithstanding):
> >
> > read(unit=1, fmt=*, iostat=ios) variable_name, variable_value
>
> I have not, and I've used this kind of thing on more compilers than can
> easily be counted, even since it was introduced in f77. It would be
> helpful if you would specify exactly what *DID* happen instead of just
> that it "did not do what you expect". My guess is that your expectations
> ran contrary to the standard, but there is no way I can verify that from
> the information given. I cannot agree to recommendations based on a
> single vague and unverified claim.
>
> For example, if the value has any special characters (a / as often found
> in pathnames is one example), the result might surprise you, but that
> would be in accordance with the standard.
>
> There are lots of other possibilities that might surprise you, but are
> still in accordance with the standard. I don't think I'll try to list
> them all.
>
> > If you are interested in portability, then do the original read with
> > formatted input rather than list-directed input:
>
> I'll give my knee-jerk reaction to this common error. List-directed
> input is a form of formatted input. In fact, the long-winded term is
> "list-directed formatting", although you mostly won't see people being
> quite that verbose outside of the standard. What you are referring to is
> explicit formatting as opposed to list-directed formating. Yes,
> programming errors do result from this terminology error, so it is more
> than just a pointless nitpick.

Hmmm. I will have to go through old code and compiler docs, and get
back to you on that in a day or two. What I remember for sure was when
a new compiler broke old code because of the "reads to end of line"
rule, that was the day I stopped trusting list-directed string input.

--Dave
From: Richard Maine on
Dave Allured <nospom(a)indra.com> wrote:

> Hmmm. I will have to go through old code and compiler docs, and get
> back to you on that in a day or two. What I remember for sure was when
> a new compiler broke old code because of the "reads to end of line"
> rule, that was the day I stopped trusting list-directed string input.

I'm not sure what you mean by "reads to end of line rule", but it sounds
like one of two possibilities to me, both covered by the standard rather
than being portability issues.

1. The read stops before the end of the line. That would happen with
list-directed input if your data had a slash that was not quoted.
Indeed, that can be a "gotcha", but it is scarcely reason to throw out
all of list-directed input for. There are plenty of gotchas in all forms
of input.

2. The read goes past the end of the line. That would happen with
list-directed input if there were insufficient data fields on the line
for the variables. One might have been assuming that this would give a
zero or blank value, or perhaps leave the variable value unchanged.
Again, that is something one should be aware of, but it doesn't justify
throwing out the whole feature.

List-directed input is not always the best answer. The above issues can
be signals of situations where it might be better to use something else.
I could well imagine, for example, wanting to read a single line and
nothing but that line, giving special treatment to a blank field
(perhaps taking it to mean some default or perhaps flagging it as an
error). Almost sounds like that's the kind of scenario you might be
talking about, in which case I might well agree with your decision for
the particular case.

Error handling is probably one of the weaker points of list-directed
input.

So I can see plenty of reasons to avoid it in some situations. But I do
think those reasons should be concrete ones like the above rather than
"I once had a problem of some kind with list-directed input, so any use
of list-directed input is suspect".

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain