From: Bart Vandewoestyne on
A student of mine asked an interesting question today... and i
didn't really know how to answer it, so here we go...

Suppose you have a file test.txt containing lines of integer or
floating point numbers. Suppose the number of columns of that file is
larger than than the default that your compiler can handle. Then the RECL
specifier can help, something like

integer, dimension(1000) :: A

open(unit=10, file="test.txt", action="read", &
status="old", position="rewind", recl=10000)
read(unit=10, fmt=*) A

But what if you want to read this same file using standard input? Say
you want to do something like

../program < test.txt

with the same test.txt that has more columns than allowed by the default
of the compiler.

Apparently, something like

read(unit=*, fmt=*) A

does not work here, and the RECL does not seem to exist for a read
statement...

What's the solution here?

Thanks,
Bart

--
"Share what you know. Learn what you don't."
From: dpb on
Bart Vandewoestyne wrote:
....
> Suppose you have a file test.txt containing lines of integer or
> floating point numbers. Suppose the number of columns of that file is
> larger than than the default that your compiler can handle. Then the RECL
> specifier can help, ...[open example elided]
> But what if you want to read this same file using standard input? Say
> you want to do something like
>
> ./program < test.txt
>
> with the same test.txt that has more columns than allowed by the default
> of the compiler.
....
> read(unit=*, fmt=*) A
> does not work here, and the RECL does not seem to exist for a read
> statement...
....

I think the answer is that if the input file format doesn't conform to
the expectations of the program, there isn't necessarily any solution
other than to solve the mismatch by modifying either the input or the
program--but that's probably not the fundamental question of how to
write a _totally_ generic input statement.

Only way I see would be to have the flexibility built into the program
to look at the file either as auxiliary input or by parsing it in
another format such as scanning it as text then using the RECL
appropriate. Of course, even there one may run into physical
limitations of the hardware or the compiler.

--
From: Richard Maine on
Bart Vandewoestyne <MyFirstName.MyLastName(a)telenet.be> wrote:

> Suppose the number of columns of that file is
> larger than than the default that your compiler can handle. Then the RECL
> specifier can help, something like...

Yes. Though I note that the default limit tends to be larger these days
with many compilers than it used to. Still, for maximum portability, it
is good to specify a recl if there is ay chnce it might be needed.

> But what if you want to read this same file using standard input?
....
> Apparently, something like
>
> read(unit=*, fmt=*) A
>
> does not work here,

By "does not work", I assume you mean that it doesn't have a way to
specify a recl other than the default. The read statement is no
different whether you are using standard input or some other file. It is
only the OPEN statement that has "issues".


> and the RECL does not seem to exist for a read
> statement...

Correct. You specify it in the OPEN.

> What's the solution here?

Probably the most portable answer is not to use redirection for files
that don't conform to the default expectations for standard input.
Otherwise, well...

The answer is to use the OPEN statement. That's the only place you can
specify recl. But using OPEN with standard input has portability issues.
One of the issues is finding the unit number. You can't use open with
unit=* (that has the fundamental problem that there are two different *
units - one for input and one for output - and it would be ambiguous
which one was intended). So you need to find a numeric unit number that
corresponds to standard input.

F2003 guarantees that there is such a numeric unit number and provides a
standard way to find it (the INPUT_UNIT named constant in the
ISO_FORTRAN_ENVIRONMENT intrinsic module). Prior to f2003 there is no
guarantee that there even is such a unit number, much less what it is.
Unit 5 is a common choice, but sometimes there are subtle distinctions
between unit 5 and standard input, particularly when redirection is
involved.

What you want is a reopen on the same unit, changing the recl value. Go
ahead and try it. It might work. But, as I said above, it has
portability issues, particularly prior to f2003. It may well be that
some f95 compilers just don't support reopening standard input at all.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
From: Bart Vandewoestyne on
On 2008-04-09, Richard Maine <nospam(a)see.signature> wrote:
>
> The answer is to use the OPEN statement. That's the only place you can
> specify recl. But using OPEN with standard input has portability issues.
> One of the issues is finding the unit number. You can't use open with
> unit=* (that has the fundamental problem that there are two different *
> units - one for input and one for output - and it would be ambiguous
> which one was intended). So you need to find a numeric unit number that
> corresponds to standard input.
>
> F2003 guarantees that there is such a numeric unit number and provides a
> standard way to find it (the INPUT_UNIT named constant in the
> ISO_FORTRAN_ENVIRONMENT intrinsic module). Prior to f2003 there is no
> guarantee that there even is such a unit number, much less what it is.
> Unit 5 is a common choice, but sometimes there are subtle distinctions
> between unit 5 and standard input, particularly when redirection is
> involved.

OK. Let's say I can live with the fact of using a hardcoded
numerical value for the unit number of standard input, say number 5...

> What you want is a reopen on the same unit, changing the recl value. Go
> ahead and try it. It might work. But, as I said above, it has
> portability issues, particularly prior to f2003. It may well be that
> some f95 compilers just don't support reopening standard input at all.

I'm afraid that I don't understand what you mean by 'a reopen on
the same unit'. I tried this

open(unit=5, action="read", status="old", position="rewind", recl=10000)
read(unit=5, fmt=*) A

but this gives me

Attempt to open a file that is already connected (open)
Program terminated by fatal I/O error
Aborted

I also tried several variations of the above but couldn't get it working.
I also tried adding

close(unit=5)

before the open statement, but that also didn't help.

I checked my M&R book on the section describing the 'open' statement, but
i could not figure out what you mean by a 're-open of unit 5'.

Can you specify that a bit more in terms of a code-example?

Thanks,
Bart

--
"Share what you know. Learn what you don't."
From: dpb on
Bart Vandewoestyne wrote:
> On 2008-04-09, Richard Maine <nospam(a)see.signature> wrote:
....
>> What you want is a reopen on the same unit, changing the recl value. Go
>> ahead and try it. It might work. But, as I said above, it has
>> portability issues, particularly prior to f2003. It may well be that
>> some f95 compilers just don't support reopening standard input at all.
>
> I'm afraid that I don't understand what you mean by 'a reopen on
> the same unit'. I tried this
>
> open(unit=5, action="read", status="old", position="rewind", recl=10000)
> read(unit=5, fmt=*) A
>
> but this gives me
>
> Attempt to open a file that is already connected (open)
....

That's exactly the symptom Richard indicated you might see. Standard
input is "connected" by default and so any attempt to use OPEN() on it
is, by definition reopening it.

The compiler just told you it tried to open an already open file (we
knew that) and that you can't do that (and there's since that isn't
required, we can't say that's a problem).

For this case I can only suggest you might try to see if you can CLOSE()
standard output, _THEN_ reopen it. No guarantees that will let you
succeed, either.

As Richard says, this is all in the arena of nonstandard, nonportable
behavior.

--