reading data from file

  • Follow


Hello forum (yeah it is me again).
I am trying to read a real data from a file. I use a string character
(STRING) as a variable to indicate me where is my data. My real data
is
next to this string (' AVERAGE STATION PRESSURE:'). I want to detect
the string and stay in the line to read my real data.
Here is my routine:

SUBROUTINE load_psurf(fname,psurf)
INTEGER :: fOpenStatus,fInputStatus
CHARACTER(10) :: fileInput
CHARACTER(26) :: STRING
CHARACTER(30),INTENT(IN) :: fname
REAL,INTENT(OUT) :: psurf
fileInput = fname(1:6)//'.dat'
OPEN(UNIT = 11, FILE = fileInput,STATUS='OLD',IOSTAT = fOpenStatus)
IF (fOpenStatus > 0) STOP '* File does not exist! *'
DO
 READ(11, *,IOSTAT=fInputStatus)STRING
 IF (STRING == ' AVERAGE STATION PRESSURE:')
    READ(11, 20) psurf
 IF (fInputStatus /= 0) EXIT
 20 FORMAT(F11.3)
END DO
END SUBROUTINE load_psurf


And the file (where '***' means some other data):

'file01.dat'
----------

************
************
 1159  0.00                   2359  0.00


      DAILY PRESSURE SUMMARY FOR 04/15/12

 HOURLY STATION PRESSURE VALUES:

 1151Z  26.235
 1751Z  26.285
 2351Z  26.145
 0551Z  26.135

 AVERAGE STATION PRESSURE:    26.200 [inches of mercury]
**************
**************


I tried my call to the subroutine and got this message:

IF (STRING == ' AVERAGE STATION PRESSURE:')
 
1
Error: Cannot assign to a named constant at (1)

Any suggestion is appreciated.
Thanks
0
Reply medina.rc (51) 1/10/2012 5:04:42 AM

On Jan 10, 4:04=A0pm, ritchie31 <medina...@gmail.com> wrote:
> Hello forum (yeah it is me again).
> I am trying to read a real data from a file. I use a string character
> (STRING) as a variable to indicate me where is my data. My real data
> is
> next to this string (' AVERAGE STATION PRESSURE:'). I want to detect
> the string and stay in the line to read my real data.
> Here is my routine:
>
> SUBROUTINE load_psurf(fname,psurf)
> INTEGER :: fOpenStatus,fInputStatus
> CHARACTER(10) :: fileInput
> CHARACTER(26) :: STRING
> CHARACTER(30),INTENT(IN) :: fname
> REAL,INTENT(OUT) :: psurf
> fileInput =3D fname(1:6)//'.dat'
> OPEN(UNIT =3D 11, FILE =3D fileInput,STATUS=3D'OLD',IOSTAT =3D fOpenStatu=
s)
> IF (fOpenStatus > 0) STOP '* File does not exist! *'
> DO
> =A0READ(11, *,IOSTAT=3DfInputStatus)STRING
> =A0IF (STRING =3D=3D ' AVERAGE STATION PRESSURE:')

This statement is incomplete.  Missing '&' from the end of line,
so that the next line will be considered to be a continuation.

> =A0 =A0 READ(11, 20) psurf
> =A0IF (fInputStatus /=3D 0) EXIT
> =A020 FORMAT(F11.3)
> END DO
> END SUBROUTINE load_psurf
> I tried my call to the subroutine and got this message:
>
> IF (STRING =3D=3D ' AVERAGE STATION PRESSURE:')
>
> 1
> Error: Cannot assign to a named constant at (1)

See above.
0
Reply louisa.hutch (142) 1/10/2012 6:21:03 AM


On Jan 9, 9:04=A0pm, ritchie31 <medina...@gmail.com> wrote:
> Hello forum (yeah it is me again).
> I am trying to read a real data from a file. I use a string character
> (STRING) as a variable to indicate me where is my data. My real data
> is
> next to this string (' AVERAGE STATION PRESSURE:'). I want to detect
> the string and stay in the line to read my real data.
> Here is my routine:
>
> SUBROUTINE load_psurf(fname,psurf)
> INTEGER :: fOpenStatus,fInputStatus
> CHARACTER(10) :: fileInput
> CHARACTER(26) :: STRING
> CHARACTER(30),INTENT(IN) :: fname
> REAL,INTENT(OUT) :: psurf
> fileInput =3D fname(1:6)//'.dat'
> OPEN(UNIT =3D 11, FILE =3D fileInput,STATUS=3D'OLD',IOSTAT =3D fOpenStatu=
s)
> IF (fOpenStatus > 0) STOP '* File does not exist! *'
> DO
> =A0READ(11, *,IOSTAT=3DfInputStatus)STRING
> =A0IF (STRING =3D=3D ' AVERAGE STATION PRESSURE:')
> =A0 =A0 READ(11, 20) psurf
> =A0IF (fInputStatus /=3D 0) EXIT
> =A020 FORMAT(F11.3)
> END DO
> END SUBROUTINE load_psurf
>
> And the file (where '***' means some other data):
>
> 'file01.dat'
> ----------
>
> ************
> ************
> =A01159 =A00.00 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 2359 =A00.00
>
> =A0 =A0 =A0 DAILY PRESSURE SUMMARY FOR 04/15/12
>
> =A0HOURLY STATION PRESSURE VALUES:
>
> =A01151Z =A026.235
> =A01751Z =A026.285
> =A02351Z =A026.145
> =A00551Z =A026.135
>
> =A0AVERAGE STATION PRESSURE: =A0 =A026.200 [inches of mercury]
> **************
> **************
>
> I tried my call to the subroutine and got this message:
>
> IF (STRING =3D=3D ' AVERAGE STATION PRESSURE:')
>
> 1
> Error: Cannot assign to a named constant at (1)
>
> Any suggestion is appreciated.
> Thanks

Which compiler are you using?

What happens if you substitute ".EQ." for "=3D=3D"?

Bob Corbett
0
Reply robert.corbett (96) 1/10/2012 7:09:49 AM

On Jan 9, 10:21=A0pm, Louisa <louisa.hu...@gmail.com> wrote:
> On Jan 10, 4:04=A0pm, ritchie31 <medina...@gmail.com> wrote:
>
>
>
>
>
>
>
>
>
> > Hello forum (yeah it is me again).
> > I am trying to read a real data from a file. I use a string character
> > (STRING) as a variable to indicate me where is my data. My real data
> > is
> > next to this string (' AVERAGE STATION PRESSURE:'). I want to detect
> > the string and stay in the line to read my real data.
> > Here is my routine:
>
> > SUBROUTINE load_psurf(fname,psurf)
> > INTEGER :: fOpenStatus,fInputStatus
> > CHARACTER(10) :: fileInput
> > CHARACTER(26) :: STRING
> > CHARACTER(30),INTENT(IN) :: fname
> > REAL,INTENT(OUT) :: psurf
> > fileInput =3D fname(1:6)//'.dat'
> > OPEN(UNIT =3D 11, FILE =3D fileInput,STATUS=3D'OLD',IOSTAT =3D fOpenSta=
tus)
> > IF (fOpenStatus > 0) STOP '* File does not exist! *'
> > DO
> > =A0READ(11, *,IOSTAT=3DfInputStatus)STRING
> > =A0IF (STRING =3D=3D ' AVERAGE STATION PRESSURE:')
>
> This statement is incomplete. =A0Missing '&' from the end of line,
> so that the next line will be considered to be a continuation.
>
> > =A0 =A0 READ(11, 20) psurf
> > =A0IF (fInputStatus /=3D 0) EXIT
> > =A020 FORMAT(F11.3)
> > END DO
> > END SUBROUTINE load_psurf
> > I tried my call to the subroutine and got this message:
>
> > IF (STRING =3D=3D ' AVERAGE STATION PRESSURE:')
>
> > 1
> > Error: Cannot assign to a named constant at (1)
>
> See above.

You nailed it.  I was looking at the expression, and I missed error in
the larger context.

I would like to suggest another fix, which is to add "THEN" to the end
if the IF statement and an "END IF" following the READ statement.

Bob Corbett
0
Reply robert.corbett (96) 1/10/2012 7:25:32 AM

<robert.corbett@oracle.com> wrote:

> On Jan 9, 10:21 pm, Louisa <louisa.hu...@gmail.com> wrote:
> > On Jan 10, 4:04 pm, ritchie31 <medina...@gmail.com> wrote:
....
> > >  READ(11, *,IOSTAT=fInputStatus)STRING
> > >  IF (STRING == ' AVERAGE STATION PRESSURE:')
> >
> > This statement is incomplete.  Missing '&' from the end of line,
> > so that the next line will be considered to be a continuation.
> >
> You nailed it.  I was looking at the expression, and I missed error in
> the larger context.
> 
> I would like to suggest another fix, which is to add "THEN" to the end
> if the IF statement and an "END IF" following the READ statement.

Either of those fixes might get it to compile, but it still won't
actually work correctly. In my initial skim, I first saw the other
problem (um, that is one of the other problems); I had to go back and
recheck when I got down to the question and found that it was a
compilation error instead of the issue I expected.

With list-directed input, STRING is not going to have a value like
'AVERAGE STATION PRESSURE:' unless that string is quoted in the input
file (which it isn't, per the sample shown). List-directed input sees
blanks as field delimitters, so the value will be just 'AVERAGE', which
isn't going to work.

I'm slightly puzzled how the OP could think that this could ever work as
expected. I could understand thinking that the whole line might end up
being read into the character varable. That's not what happens, but I
could at least understand thinking that. But the code shown requires
that the string get neither the whole line nor the first delimitted
field. I can't see how it is supposed to get what the OP hoped other
than by clairvoyance, as there is nothing special to indicate that the
string would get that much of the line, but no more.

Speaking of which, I now see yet another problem in the subsequent read
(which I already elided above before noticing that it had  problem). The
subsequent read appears intended to read the next field on the same line
as the string. But that won't happen. The subsequent read would instead
read the first field on the next line. List-directed input is not
compatible with non-advancing, so that won't solve the problem.

I would probably read the whole line into a character variable (using an
explicit format of '(a)' - not list-directed, which would get only the
first field). Then I'd just test whether the first part of the line was
equal to the expected string. (Well, I'd most likely make the test
case-insensitive and also handle possible leading blanks just to make it
a bit more robust, but that's more than the OP probably needs). Then I'd
probably use list-directed internal read of the remainder of the line to
get the numeric data value. Using an explicit format for the numeric
data value seems to be just asking for additional errors such as getting
the exact columns off by one; I don't see the advantage.

-- 
Richard Maine                    | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle           |  -- Mark Twain
0
Reply nospam47 (9742) 1/10/2012 8:09:03 AM

On 10 jan, 09:09, nos...@see.signature (Richard Maine) wrote:
> I would probably read the whole line into a character variable (using an
> explicit format of '(a)' - not list-directed, which would get only the
> first field). Then I'd just test whether the first part of the line was
> equal to the expected string. (Well, I'd most likely make the test
> case-insensitive and also handle possible leading blanks just to make it
> a bit more robust, but that's more than the OP probably needs). Then I'd
> probably use list-directed internal read of the remainder of the line to
> get the numeric data value. Using an explicit format for the numeric
> data value seems to be just asking for additional errors such as getting
> the exact columns off by one; I don't see the advantage.
>

This could be something along these lines:

do
    read( 11, '(a)' ) string

    if ( index( string, 'AVERAGE STATION PRESSURE:' ) > 0 ) THEN
        k = index( string, ':' )
        read( string(k+1), * ) value
    endif
enddo

(leaving out a few details)

Regards,

Arjen
0
Reply arjen.markus895 (633) 1/10/2012 10:15:45 AM

This code produces the desired result:

Program main
Character(30):: fname
Real:: psurf
fname="test"
Call load_psurf(fname,psurf)
Write(6,*)psurf
End

Subroutine load_psurf(fname,psurf)
Integer :: fOpenStatus,fInputStatus
Character(10) :: fileInput
Character(80) :: STRING
Character(30),Intent(IN) :: fname
Character(20) :: psurf1,psurf2,psurf3
Real,Intent(OUT) :: psurf
fileInput = trim(fname)//'.dat'
Open(Unit = 11, File = fileInput,Status='OLD',Iostat = fOpenStatus)
If (fOpenStatus > 0) Stop '* File does not exist! *'
Do
 Read(11,"(A80)",Iostat=fInputStatus)STRING
 If (trim(STRING(1:26)) .EQ. trim(' AVERAGE STATION PRESSURE:'))Then
    Read(string(27:37), "(G11.3)") psurf
 EndIf
 If (fInputStatus /= 0) Exit
EndDo
End Subroutine load_psurf


0
Reply michael.caracotsios1 (9) 1/10/2012 11:48:21 AM

On Tue, 10 Jan 2012 03:15:45 -0700, Arjen Markus  
<arjen.markus895@gmail.com> wrote:

>
> This could be something along these lines:
>
> do
>     read( 11, '(a)' ) string
>
>     if ( index( string, 'AVERAGE STATION PRESSURE:' ) > 0 ) THEN
>         k = index( string, ':' )
>         read( string(k+1), * ) value

That won't work either.  Try:

          read( string(k+1:), * ) value

-- 
John
0
Reply jwmwalrus (131) 1/10/2012 3:48:59 PM

Michael <michael.caracotsios@gmail.com> wrote:

> This code produces the desired result:

Yep, looks like it. A few minor coments.

> Character(30),Intent(IN) :: fname

I realize the above line was in the OP's code, but I didn't comment on
it before, so I'll do so now. Using explicit length for a dummy
character argument is almost always a bad idea. It rarely does anything
at all useful (specifically, no, it does not tend to generate warnings
if the length is wrong), but it can cause some confusing bugs. This
particular case doesn't illustrate any of the bugs, but I wouldn't do it
this way anyway. I recommend declaring the length of the dummy argument
as (*).

>  If (trim(STRING(1:26)) .EQ. trim(' AVERAGE STATION PRESSURE:'))Then

Why the trims? They can't possibly do anything useful. Note that .eq.
ignores trailing blanks in all cases, so there is never any reason to
use trim in string equality tests. The strings 'XYZ' and 'XYZ   ' will
test as equal. The trim of the literal constant strikes me as
particularly odd, as the constant clearly has no trailing blanks.

-- 
Richard Maine                    | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle           |  -- Mark Twain
0
Reply nospam47 (9742) 1/10/2012 5:00:32 PM

On 10 jan, 16:48, JWM <jwmwal...@gmail.com> wrote:
> On Tue, 10 Jan 2012 03:15:45 -0700, Arjen Markus
>
> <arjen.markus...@gmail.com> wrote:
>
> > This could be something along these lines:
>
> > do
> > =A0 =A0 read( 11, '(a)' ) string
>
> > =A0 =A0 if ( index( string, 'AVERAGE STATION PRESSURE:' ) > 0 ) THEN
> > =A0 =A0 =A0 =A0 k =3D index( string, ':' )
> > =A0 =A0 =A0 =A0 read( string(k+1), * ) value
>
> That won't work either. =A0Try:
>
> =A0 =A0 =A0 =A0 =A0 read( string(k+1:), * ) value
>
> --
> John

Oops - you're quite right.

Regards,

Arjen
0
Reply arjen.markus895 (633) 1/11/2012 8:35:08 AM

On Jan 10, 4:48=A0am, Michael <michael.caracots...@gmail.com> wrote:
> This code produces the desired result:
>
> Program main
> Character(30):: fname
> Real:: psurf
> fname=3D"test"
> Call load_psurf(fname,psurf)
> Write(6,*)psurf
> End
>
> Subroutine load_psurf(fname,psurf)
> Integer :: fOpenStatus,fInputStatus
> Character(10) :: fileInput
> Character(80) :: STRING
> Character(30),Intent(IN) :: fname
> Character(20) :: psurf1,psurf2,psurf3
> Real,Intent(OUT) :: psurf
> fileInput =3D trim(fname)//'.dat'
> Open(Unit =3D 11, File =3D fileInput,Status=3D'OLD',Iostat =3D fOpenStatu=
s)
> If (fOpenStatus > 0) Stop '* File does not exist! *'
> Do
> =A0Read(11,"(A80)",Iostat=3DfInputStatus)STRING
> =A0If (trim(STRING(1:26)) .EQ. trim(' AVERAGE STATION PRESSURE:'))Then
> =A0 =A0 Read(string(27:37), "(G11.3)") psurf
> =A0EndIf
> =A0If (fInputStatus /=3D 0) Exit
> EndDo
> End Subroutine load_psurf

Michael, thanks a lot! I works fine. And thanks all of you for your
cooperation.
0
Reply medina.rc (51) 1/12/2012 10:22:49 AM

10 Replies
45 Views

(page loaded in 0.129 seconds)

Similiar Articles:













7/10/2012 8:18:41 PM


Reply: