[comp.os.vms] Checking a string for an integer

dsroberts@biivax.dp.beckman.com (04/02/91)

I would like to take a 3 byte string and find out if it contains only ascii
digits for number or if letters were entered.  On VMS, the DCL command would be

result = f$integer (string)

which would put the numeric equivalent in result, or return an error.  I don't
find an obvious way to do this in FORTRAN.  Any suggestions?  I am not averse
to a VMS system service, btw.

And, just in case I am missing some better alternative, what I am trying to
accomplish is to find out if this 3 byte string contains a number in a valid
range (in this case 1-254) or not.  The only requirement is that I start with a
3-byte string.  Pointers to the appropriate pages in the VMS FORTRAN manuals
would be appreciated :-)
-- 
---------------------------------------------------------------------------
   Don Roberts                   Internet:  dsroberts@beckman.com
   Beckman Instruments, Inc.     Yellnet:   714/961-3029
   2500 Harbor Bl. Mailstop X-12 FAX:       714/961-3351
   Fullerton, CA  92634          Disclaimer:  Always
---------------------------------------------------------------------------

8099pierzina@vmsd.csd.mu.edu (Todd Pierzina) (04/02/91)

In article <1991Apr1.104227.243@biivax.dp.beckman.com>, dsroberts@biivax.dp.beckman.com writes:
>I would like to take a 3 byte string and find out if it contains only ascii
>digits for number or if letters were entered.  On VMS, the DCL command would be
>result = f$integer (string)
>which would put the numeric equivalent in result, or return an error.  I don't
>find an obvious way to do this in FORTRAN...
>And, just in case I am missing some better alternative, what I am trying to
>accomplish is to find out if this 3 byte string contains a number in a valid
>range (in this case 1-254) or not.  The only requirement is that I start with a
>3-byte string... 

    character String*3
    integer i, iostat

    ...

    read (String, '(I3)', err=1000, iostat=iostat) i
    if ((1 .lt. 1) .or. (i .gt. 254)) then goto 1010

1000	[not numeric error handler]
1010	[out of range error handler]

Todd Pierzina                 8099pierzina@vms.csd.mu.edu
Student Programmer            robertf@marque.mu.edu
Marquette University          todd@studsys.mu.edu
[Looking through old issues of Readers' Digest for a cute saying]

jerry@heyman.austin.ibm.com (Jerry Heyman) (04/02/91)

In article <1991Apr1.104227.243@biivax.dp.beckman.com> dsroberts@biivax.dp.beckman.com writes:
>I would like to take a 3 byte string and find out if it contains only ascii
>digits for number or if letters were entered.  On VMS, the DCL command would be
>
>result = f$integer (string)
>

You could always use an internal READ statement.  You would also have to
specifiy an error state on the READ to handle alphabetic input when its not
expected.

Something like:

      READ (string, 'I3', error=xxx) result

where xxx is a line number where the code should branch to if an error occurs.
Its been a while since I tried this, so the syntax might be a little rough, but
you get the general idea.

jerry
-- 
Jerry Heyman                         Internet : jerry@ajones.austin.ibm.com
PSP Development Environment Tools    VNET     : HEYMAN at AUSTIN
Austin, TX  78758                    IBM T-R  : jerry@heyman.austin.ibm.com
*** All opinions expressed are exactly that - my opinions and NOT IBM's

ereiamjh@jhunix.HCF.JHU.EDU (Tom B. O'Toole) (04/02/91)

In article <1991Apr1.104227.243@biivax.dp.beckman.com> dsroberts@biivax.dp.beckman.com writes:
>I would like to take a 3 byte string and find out if it contains only ascii
>digits for number or if letters were entered.  On VMS, the DCL command would be
>
>result = f$integer (string)
>
It's very easy to do. You basically do something like:
	character*3 string
...
	read(string,*,err=99)input
...
99	WRITE(6,*) 'a non integer string representation'

This is an 'internal' read, and is a lot more intuitive than the old
encode/decode statements. You replace the unit number with 
a character variable.  Documentation is in the chapter on 
input/output statments. Note: old versions
of the VMS fortran runtime system would not let you use an implicit format
specifier, you would have had to use I3 or similar. I'm not sure when this was
fixed. 
-- 
Tom O'Toole - ecf_stbo@jhuvms.bitnet - JHUVMS system programmer 
Homewood Computing Facilities, Johns Hopkins University, Balto. Md. 21218 
ease!Trim!eeeaaaassse!trimtrimtrimeeeeeeaaaaassetrimease!trim!ease!trimeaase

KENCB@SLACVM.SLAC.STANFORD.EDU (04/02/91)

In article <1991Apr1.104227.243@biivax.dp.beckman.com>,
dsroberts@biivax.dp.beckman.com says:
>
>I would like to take a 3 byte string and find out if it contains only ascii
>digits for number or if letters were entered.  On VMS, the DCL command would
>be
>
>result = f$integer (string)
>
>which would put the numeric equivalent in result, or return an error.  I don't
>find an obvious way to do this in FORTRAN.  Any suggestions?  I am not averse
>to a VMS system service, btw.
>

    How about using the OTS$CVT_TI_L system service.  OTS will return
a FALSE status if it can't convert the text string.   Sample code:

        INTEGER*4   IVAL, OTS$CVT_TI_L
        CHARACTER*3 CVAL
          .
          .
        READ (5,*) CVAL
        IF (OTS$CVT_TI_L (CVAL, IVAL, %VAL(4), %VAL('11'X))) THEN
          IF (IVAL.GE.1 .AND. IVAL.LE.254) THEN
            .
            .
          ELSE
            .
          ENDIF
        ELSE
          .
        ENDIF


Do a $HELP RTL OTS$ OTS$CVT_TI_L for details on the 3rd and 4th arguments.

                     Ken

 Dr. Kenneth H. Fairfield        Internet: Fairfield@Tpc.Slac.Stanford.Edu
 SLAC, P.O.Box 4349, Bin 98      DECnet:   45047::FAIRFIELD (TPC::)
 Stanford, CA   94309            BITNET    Fairfield@SlacTpc
 "These opinions are worth what you paid for 'em...
         ...and they are mine, not SLAC's, Stanford's, nor the DOE's..."

gpwrmdh@gp.co.nz (04/02/91)

In article <1991Apr1.104227.243@biivax.dp.beckman.com>, dsroberts@biivax.dp.beckman.com writes:
> I would like to take a 3 byte string and find out if it contains only ascii
> digits for number or if letters were entered.  On VMS, the DCL command would be
> 
> result = f$integer (string)
> 
> which would put the numeric equivalent in result, or return an error.  I don't
> find an obvious way to do this in FORTRAN.  Any suggestions?  I am not averse
> to a VMS system service, btw.

Here is a simple example program:

	program test
	implicit none
	
	character*3 in
	integer out, status

	write (*, fmt='(''$number: '')')

	read (*, fmt='(a3)') in
	read (unit=in, fmt='(i3)', iostat=status) out

	if (status .eq. 0) then
	    type *, 'Converted ok'
	    type *, 'Number = ', out
	    type *, 'Returned status = ', status
	    if (out .gt. 254) type *, 'Number too big'
	else
	    type *, 'Error converting number'
	    type *, 'Status = ', status
	end if

	end

Basically, you use the READ statement to convert the string to internal 
format, and check the returned status - success returns a 0. You will 
probably want more error checking than I have put in the above.

The error code returned for invalid numbers is code 64, meaning "input 
conversion error".

> 
> And, just in case I am missing some better alternative, what I am trying to
> accomplish is to find out if this 3 byte string contains a number in a valid
> range (in this case 1-254) or not.  The only requirement is that I start with a
> 3-byte string.  Pointers to the appropriate pages in the VMS FORTRAN manuals
> would be appreciated :-)

Section 4.2.3.2 of the Fortran User's manual (V5.0) has a little about
internal i/o, and also section 7.2.4 of the Fortran Reference Manual.

> -- 
> ---------------------------------------------------------------------------
>    Don Roberts                   Internet:  dsroberts@beckman.com
>    Beckman Instruments, Inc.     Yellnet:   714/961-3029
>    2500 Harbor Bl. Mailstop X-12 FAX:       714/961-3351
>    Fullerton, CA  92634          Disclaimer:  Always
> ---------------------------------------------------------------------------
-- 
----------------------------------------------------------------------------
Martin D. Hunt			
GP Print Limited		USEnet address : martinh@gp.co.nz
Wellington			PSI address    : PSI%0530147000028::martinh
New Zealand			Phone	       : +64 4 4965790
-----------------------------------------------------------------------------

dsroberts@biivax.dp.beckman.com (04/02/91)

Many thanks to the legion who responded to my posting.  To summarize, the two
most useful (for my purposes) suggestions:

- Use LIB$CVT_DTB (a VMS RTL service) I received two responses with this
- Use Internal READ (with format (BN,I3) so I can have left justification)
  I think I must have received 1000 responses with this. 

The library routine is a little better for my uses.  Now, can you PLEASE stop
responding ? :-)
-- 
---------------------------------------------------------------------------
   Don Roberts                   Internet:  dsroberts@beckman.com
   Beckman Instruments, Inc.     Yellnet:   714/961-3029
   2500 Harbor Bl. Mailstop X-12 FAX:       714/961-3351
   Fullerton, CA  92634          Disclaimer:  Always
---------------------------------------------------------------------------