From: ivan martin on
Good day everyone,
please, I plead for your help.

In fortran, what would be a practical way to read a line that can
look like

A 1. 2. 3. (numbers are made up, they do not increase like this)
Z
A 1. 2. 3.

so, I wish to read a char and three numbers following it if the char is an "A", but
read the char and quit reading at that point, if the char is a "Z".

(Z marks the last line with numbers in my input file; other chars mark properties
of points; so behind Z there will never be numbers).

If I read it simply like
read(unit=..., *)char,num1,num2,num3

then program will report an error if he does not encounter the numbers after Z.

I would be thankful for any help you can give.
Ivan
From: Bruce Bowler on
On Tue, 27 Apr 2010 14:12:27 +0200, ivan martin set fingers to keyboard
and typed:

> Good day everyone,
> please, I plead for your help.
>
> In fortran, what would be a practical way to read a line that can look
> like
>
> A 1. 2. 3. (numbers are made up, they do not increase like this) Z
> A 1. 2. 3.
>
> so, I wish to read a char and three numbers following it if the char is
> an "A", but read the char and quit reading at that point, if the char is
> a "Z".
>
> (Z marks the last line with numbers in my input file; other chars mark
> properties of points; so behind Z there will never be numbers).
>
> If I read it simply like
> read(unit=..., *)char,num1,num2,num3
>
> then program will report an error if he does not encounter the numbers
> after Z.
>
> I would be thankful for any help you can give. Ivan


Pseudo code

character(len="long enough"):: line
read (5,*) line
if (line(1:1) /= "Z") then
read (line(2:end),*) num1,num2,num3
more processing
endif



--
+-------------------+---------------------------------------------------+

Bruce Bowler | One nice thing about egotists: They don't talk

1.207.633.9610 | about other people.

bbowler(a)bigelow.org | - Lucille S. Harper

+-------------------+---------------------------------------------------+

From: Jim Xia on
On Apr 27, 8:55 am, Bruce Bowler <bbow...(a)bigelow.org> wrote:
> On Tue, 27 Apr 2010 14:12:27 +0200, ivan martin set fingers to keyboard
> and typed:
>
>
>
>
>
> > Good day everyone,
> > please, I plead for your help.
>
> > In fortran, what would be a practical way to read a line that can look
> > like
>
> > A 1. 2. 3. (numbers are made up, they do not increase like this) Z
> > A 1. 2. 3.
>
> > so, I wish to read a char and three numbers following it if the char is
> > an "A", but read the char and quit reading at that point, if the char is
> > a "Z".
>
> > (Z marks the last line with numbers in my input file; other chars mark
> > properties of points; so behind Z there will never be numbers).
>
> > If I read it simply like
> > read(unit=..., *)char,num1,num2,num3
>
> > then program will report an error if he does not encounter the numbers
> > after Z.
>
> > I would be thankful for any help you can give. Ivan
>
> Pseudo code
>
> character(len="long enough"):: line
> read (5,*) line
> if (line(1:1) /= "Z") then
>         read (line(2:end),*) num1,num2,num3
>         more processing
> endif

"read (5,*) line" wouldn't work as the input data look like "A 1. 2.
3.". Only "A" will be read in. What you want is
"read (5, '(a)') line"

Then the issue is leading character may be blank if the input has
leading blanks. You have to use intrinsics like ADJUSTL() to remove
the leading blanks.


I'd suggest to use iostat= specifier to handle the error. It'll
result in more robust code. However the flip side of the approach
will be the dependencies on specific iostat values returned by
different compilers. So choose the one you feel comfortable.


Cheers,

Jim
From: Dan Nagle on
Hello,

On 2010-04-27 10:52:36 -0400, Jim Xia <jimxia(a)hotmail.com> said:

> "read (5,*) line" wouldn't work as the input data look like "A 1. 2.
> 3.". Only "A" will be read in. What you want is
> "read (5, '(a)') line"

I think there should be an advance= 'no' or a backspace( 5)
in there somewhere. backspacing may be problematic
if 5 is stdin.

<snip>

> I'd suggest to use iostat= specifier to handle the error. It'll
> result in more robust code. However the flip side of the approach
> will be the dependencies on specific iostat values returned by
> different compilers. So choose the one you feel comfortable.

Well, if he's sure that the only end encountered
will be end-of-line (and not end-of-file), he could test
for only iostat > 0

But iostat is a good idea IAC. And the constants
in iso_fortran_env may help.

--
Cheers!

Dan Nagle

From: Richard Maine on
Dan Nagle <dannagle(a)verizon.net> wrote:

> On 2010-04-27 10:52:36 -0400, Jim Xia <jimxia(a)hotmail.com> said:
>
> > "read (5,*) line" wouldn't work as the input data look like "A 1. 2.
> > 3.". Only "A" will be read in. What you want is
> > "read (5, '(a)') line"
>
> I think there should be an advance= 'no' or a backspace( 5)
> in there somewhere.

Those are alternative approaches. While they can also work ok in some
cases, you don't need them *ALSO*; you could use them instead.

The basic approaches commonly seen are

1. Read the whole line into a character buffer and parse the buffer
(possibly with the help of internal reads).

2. Use non-advancing I/O (or a nonstandard variant such as the $ or \
edit descriptors).

3. Use backspace

4. (sort of - I almost forgot about this one until others mentioned
simillar things) Assume that any error must be the one you might be
expecting. That's pretty full of problems, though. I disrecommend it.

Bruce (and Jim's correction) were mentioning approach 1. Approach 2 can
also work. Depends on details while is better. Sometimes it is pretty
much a coin toss or matter of personal taste. I usually recommend
against the backspace approach because it can have many problems,
including

> backspacing may be problematic if 5 is stdin.

> Well, if he's sure that the only end encountered
> will be end-of-line (and not end-of-file), he could test
> for only iostat > 0

Note that you won't ever get an "end-of-line" (more properly
end-of-record) at all from any of the codes shown. That condition
applies *ONLY* to non-advancing I/O. If you find a compiler that returns
an end-of-line condition for advancing I/O, file a bug report.

Well, that's the case through f2003 at least. I haven't checked the
f2008 FDIS on the matter. I hope it is still the case there because
otherwise it would be an incompatible change, though one of a kind that
I've occasionally seen the committee overlook. Yes, it would be an
incompatible change - not just a "new feature" to allow end-of-record
for advancing I/O. That's because f77/f90/f95/f2003 code is allowed to
assume that a negative iostat from an advancing read indicates
end-of-file. It is completely standard conforming for a program to
assume that. Thus changing it would be incompatible with existing
standard conforming programs.

(I elaborate so much because I have in the past had to explain simillar
incompatibilities to multiple people on the committee. In particular, it
came up when some people proposed to have f2003 allow multiple iostat
values to indicate eof. Apparently one vendor already had such multiple
values, not realizing that the standard prohibitted it. I objected to
changing the standard to accomodate an error made by one vendor at the
expense of invalidating existing standard-conforming codes.)

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