Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

Fortran Programming Language

newbie question for reading input file


Hi,

I don't know a lot about Fortran. The following really puzzled me:

My code below reads an input file

<fortran_code>

       READ(IN,900) ANAME,ELEV,ALAT,PRC,ODS,OSS,SS,UPS,RDCOS,AEC
   900 FORMAT(5A4,2F5.0,1X,A4,2X,A3,2X,A3,1X,A4,4X,A4,A2,1X,A4,1X,A4)
       WRITE(*,*) 'ANAME=',ANAME
       WRITE(*,*) 'ELEV=',ELEV
       WRITE(*,*) 'ALAT=',ALAT
       WRITE(*,*) 'PRC=',PRC
       WRITE(*,*) 'ODS=',ODS
       WRITE(*,*) 'OSS=',OSS
       WRITE(*,*) 'SS=',SS
       WRITE(*,*) 'UPS=',UPS
       WRITE(*,*) 'RDCOS=',RDCOS
       WRITE(*,*) 'AEC=',AEC
</fortran_code>

<input_file>
S. PRAIRIE CRK UPR  1158. 47.1 NONE       YES SUMS                AVSE
</input_file>

The output from those WRITE statements above are like this:
<output>
  ANAME=   1.0749562E+10   2.1609608E+11    160.2706       1.1015335E+13
    1.3579762E-19
  ELEV=    1158.000
  ALAT=    47.10000
  PRC=    3300.957
  ODS=   1.3563156E-19
  OSS=   1.7895340E-19
  SS=   8.8189980E+11
  UPS=   1.3563156E-19   1.3563156E-19
  RDCOS=   1.3563156E-19
  AEC=    3381.391
</output>

The whole program runs successfully. But I really have several questions:
1. ANAME should be "S. PRAIRIE CRK UPR", why output is not? Similar
question with variable SS, which should be "SUMS".
2. READ(IN, 900) has 10 variables, but 900 FORMAT(11 variables here).
Does that mean last one ("1x, A4") is ignored?

Thank you for your help.

www wrote:
> My code below reads an input file
>       READ(IN,900) ANAME,ELEV,ALAT,PRC,ODS,OSS,SS,UPS,RDCOS,AEC
>   900 FORMAT(5A4,2F5.0,1X,A4,2X,A3,2X,A3,1X,A4,4X,A4,A2,1X,A4,1X,A4)
>       WRITE(*,*) 'ANAME=',ANAME

(snip)

This is Fortran 66 code, from before CHARACTER variables.

You should change ANAME to

CHARACTER*20 ANAME

and read it with A20 format.

That is better than continuing the Fortran 66 method, which would
write it out with 5A4 format.

Also, the other items with A format should also be changed to CHARACTER.

Your FORMAT statement seems to have 15 items, I don't know which
variables are arrays and might use more than one format descriptor.

-- glen

www <w@nospam.com> wrote:
>        READ(IN,900) ANAME,ELEV,ALAT,PRC,ODS,OSS,SS,UPS,RDCOS,AEC
>    900 FORMAT(5A4,2F5.0,1X,A4,2X,A3,2X,A3,1X,A4,4X,A4,A2,1X,A4,1X,A4)
>        WRITE(*,*) 'ANAME=',ANAME
...
> <output>
>   ANAME=   1.0749562E+10   2.1609608E+11    160.2706       1.1015335E+13
>     1.3579762E-19
...
> The whole program runs successfully. But I really have several questions:
> 1. ANAME should be "S. PRAIRIE CRK UPR", why output is not? Similar
> question with variable SS, which should be "SUMS".

You don't show the declarations. Declarations are *VERY* important. It
is fairly common for people to seek help for problems that turn out to
be in the declarations, which aren't shown. That appears to be the case
here. Fortunately, this is a simple enough case that I can guess the
important part. But for future reference, be aware that declarations are
important.

ANAME and SS are of type real (either by default or explicit
declaration). That's why they print out as real values. You should
ideally declare them to be character strings instead.

This code uses a mixture of very old and newer features. The very old
feature is using a real variable to store character values. That was the
only way to do character data in Fortran 66 and earlier; there wasn't a
character type. It became nonstandard in Fortran 77 (30 years ago), even
though most f77 compilers, and many later ones as well, continued to
support the old option. Using an "A" (character) format edit descriptor
with a real variable is technically nonstandard.

Anyway, even if you are using a compiler that supports the old Hollerith
usage (that's what putting character data in noncharacter variables is
called), that won't go well with using the newer feature of
list-directed output formatting. (That's the second * in your write
(*,*)). List-directed output formatting just sees a real variable, so it
uses formatting appropriate for reals - not characters. If you are using
Hollerith, you can't output it meaningfully with list-directed output.
You have to use an explicit format with an appropriate "A" edit
descriptor, just like you did for the input. Using character variables
is better, though.

> 2. READ(IN, 900) has 10 variables, but 900 FORMAT(11 variables here).
> Does that mean last one ("1x, A4") is ignored?

First, a correction. The FORMAT doesn't have anything that corresponds
directly to variables. It has edit descriptors that define fields that
correspond to individual data items. For example, your first edit
descriptor is 5A4. That defines 5 fields. It does *NOT* necessarily
correspond to a single variable. Apparently your ANAME variable is
dimensioned with size 5, so it uses all 5 fields. But that isn't so in
general. The 5 fields could correspond to 5 separate variables.

So, counting fields defined by your FORMAT, I see 15 fields, 5 from the
5a4, 2 from the 2f10.5, and 8 more. The X edit descriptrs don't count as
defining field; they just skip columns.  I see 15 values to go with
these 15 fields. You have 10 variables; one is an array of 5 elements,
one an array of 2 elements, and 8 are scalars (at least that's what I
deduce, though you don't show the declarations). That seems to match.

Hmm. Where did you get a count of 11 of anything from. I was assuming
that you were just calling the 5a4 and 2f10.5 one thing each, but doing
that I only come up with 10. Did you just miscount? (Easy to do).

Anyway, the answer, after rephrasing in the right terms, is yes, that
unused data edit descriptors at the end of the format are ignored, even
though it doesn't look like you have that situation.

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

Richard Maine wrote:
> You have to use an explicit format with an appropriate "A" edit
> descriptor, just like you did for the input.

I see. Following outputs the string correctly:

WRITE(*,"(5A4)") ANAME

>> 2. READ(IN, 900) has 10 variables, but 900 FORMAT(11 variables here).
>> Does that mean last one ("1x, A4") is ignored?
> I see 15 values to go with
> these 15 fields. You have 10 variables; one is an array of 5 elements,
> one an array of 2 elements, and 8 are scalars (at least that's what I
> deduce, though you don't show the declarations). That seems to match.

You are right.

I have another question:

<fortran_code>

       READ(IN,900) ANAME,ELEV,ALAT,PRC,ODS,OSS,SS,UPS,RDCOS,AEC
   900 FORMAT(5A4,2F5.0,1X,A4,2X,A3,2X,A3,1X,A4,4X,A4,A2,1X,A4,1X,A4)
       WRITE(*,*) 'ALAT=',ALAT      !!outputs "ALAT=     47.10000"
       WRITE(*,"(F5.0)") ALAT    !!outputs "47."
</fortran_code>

<input_file>
S. PRAIRIE CRK UPR  1158. 47.1 NONE       YES SUMS                AVSE
</input_file>

During READ, the descriptor for ELEV is F5.0, but the value stored in it
after reading is 47.1. It seems F5.0 during READ does not have an
effect, while during WRITE does. Could you kindly explain a little more?

I think this is very important. It is "47.1", not "47.", used in the
following computation. If it is "47.", the final computation result
could be different.

The F5.0 descriptor specifies that the decimal point will be inserted
effectively at the right of the data field, if it is not supplied.  An
explicit decimal point in the data over-rides the decimal point
specification in th descriptor.

"www" <w@nospam.com> wrote in message

news:f36nbv$ups$1@news.nems.noaa.gov...

> During READ, the descriptor for ELEV is F5.0, but the value stored in it
> after reading is 47.1. It seems F5.0 during READ does not have an effect,
> while during WRITE does. Could you kindly explain a little more?

> I think this is very important. It is "47.1", not "47.", used in the
> following computation. If it is "47.", the final computation result could
> be different.

On input with Fw.d, if the value in the record contains a decimal point, the
value of d, the number of digits after the point, is ignored. This is not so
on output ("Fortran 95/2003 Explained", Section 9.12.2).

Regards,

Mike Metcalf

In a previous article, www <w@nospam.com> wrote:
 <snip>
>During READ, the descriptor for ELEV is F5.0, but the value stored in it
>after reading is 47.1. It seems F5.0 during READ does not have an
>effect, while during WRITE does. Could you kindly explain a little more?

>I think this is very important. It is "47.1", not "47.", used in the
>following computation. If it is "47.", the final computation result
>could be different.

  Decimal points in inpout have priority over specified
 format. If there is always 1 dp and you want to get rid of
it, specify f4.0,1x instead of f5.0
Chris
www wrote:

(snip)

> I see. Following outputs the string correctly:
> WRITE(*,"(5A4)") ANAME

I had thought about writing this, but using Fortran 66
A format descriptors with a string constant format.
It seems that the string constant arrived with Fortran 77,
but I don't remember seeing it used until much later.

> I have another question:

(snip)

> During READ, the descriptor for ELEV is F5.0, but the value stored in it
> after reading is 47.1. It seems F5.0 during READ does not have an
> effect, while during WRITE does. Could you kindly explain a little more?

In the days of punched cards is was often used to save one column
on the card.  Input data in, for example, F5.2 format could be
punched in five columns with an implied decimal point.

      CHARACTER*5 IN
      IN="12345"
      READ(IN,"(F5.2)") X

will read 123.45 into X.

It still might be used in disk files, but I don't know
that anyone uses it for terminal input.

(Why is it that you can't put character constants
into READ statements?)

-- glen

> (Why is it that you can't put character constants
> into READ statements?)

Because you can't have any in internal WRITE statements, and thus allowing
them in internal READs would have been an exception to a rule that was already
complicated enough?

Of course, not only can't you have character constants in such places, any
non-assignable value (e.g., PARAMETERs, expressions, ...) is not admissable.

        Jan

Jan Vorbrggen wrote:
>> (Why is it that you can't put character constants
>> into READ statements?)
> Because you can't have any in internal WRITE statements, and thus
> allowing them in internal READs would have been an exception to a rule
> that was already complicated enough?
> Of course, not only can't you have character constants in such places,
> any non-assignable value (e.g., PARAMETERs, expressions, ...) is not
> admissable.

With that argument, you would also expect no expressions in
I/O lists as in Fortran 66, which was changed in Fortran 77.

It would seem about time to fix this one.

-- glen

"Richard Maine" <nos@see.signature> wrote in message

news:1hymcnm.1wsth4i3iw8l5N%nospam@see.signature...

>                                                         If you are using
> Hollerith, you can't output it meaningfully with list-directed output.

[?]

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end

James Van Buskirk <not_va@comcast.net> wrote:

> "Richard Maine" <nos@see.signature> wrote in message
> news:1hymcnm.1wsth4i3iw8l5N%nospam@see.signature...

> >                                                         If you are using
> > Hollerith, you can't output it meaningfully with list-directed output.

> [?]

I'm not 100% certain how to interpret the "?".

It occurred to me briefly that you might be offerring your signature as
a counter-example. I'll play that game by saying that your signature
doesn't strictly speaking use Hollerith, though I'll admit it has some
relationship.

On the theory that the "?" was instead a serious question about what I
meant, I'll try to explain, though I'm not sure I can come up with a
better explanation than the OP's example. This is really going to be
little more than a repeat of that example, but with possibly confusing
extraneous things omitted, and other bits elaborated. I apologize in
advance for aiming the explanation a bit low. I'm sure that you know
most (if not all?) of this, but I'm not sure which piece you might be
missing, so I'm putting them all in.

Hollerith is the practice of storing character data in non-character
variables. Strictly speaking, it became nonstandard in f77. One simple
example of defining a variable with a Hollerith value is

    real x
    data x/4halas/

Another example, much like that of the OP, is

    real x
    read (lun,'(a4)') x

where the file might contain "alas" without the quotes.
Neither of these are strictly standard in f77 or later.(Ok, the code
isn't standard f66 either, but for unrelated reasons. I hate typing in
all caps, and I didn't feel like making a separate format statement).

In either case, the variable x has a Hollerith value "alas" (without the
quotes). This makes the nonportable assumption that a real can contain 4
Hollerith characters; assumptions like that were one of the problems of
Hollerith, but that's not the current point.

If we now go to output x using list-directed output as in

  write (*,*) x

then there is no reasonable way for the compiler to know that x contains
a Hollerith value. (Sure, it is possible in theory, with a flag
indicating whether the value is Hollerith or not, but I'll stick with my
"no reasonable way"; I've never heard of a compiler doing anything even
vaguely close.) So instead of printing anything like "alas", it will,
alas, print some strange real value depending on the internal
representations.

If you want it to print "alas", you need something to tell the compiler
to ingterpret the value in x as Hollerith. Using an explicit "a" edit
descriptor will do that, as in

   write (*,'(a4)') x

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

James Van Buskirk wrote:

> [?]

Welcome back, James. I had been wondering where you had gotten to. :o)

cheers,

paulv

--
Paul van Delst             Ride lots.
CIMSS @ NOAA/NCEP/EMC               Eddy Merckx

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc