For interactive input or for human generated input files I read the
input line by line into a character variable. The character variable is
then parsed. In this manner appropriate error messages can be generated
if the type of users input is inconsistent with the expected type.
For example if the input comprises a character variable followed a
double precision variable then a single precision then a default kind
integer such as the following:
FRED, 1.2, 2.2, 1
Then the following code fragment parses character strings with the above
format. Note that NextString, NextDouble, NextReal, NextInteger are
routines which I have developed. They extract the next token from the
string and test that the token is a character representation of the
corresponding type. If the token does represent the correct type then
the token is converted to the corresponding variable. Otherwise an error
is raised. In an interactive environment it is a simple matter to print
an error message and request the user to re-enter the data in the
correct format.
I consider such parsing code as essential for human generated input in
my own production grade applications. As suggested by M. Cohen such
parsing may be unnecessary if the input is known to be automatically
generated by a reliable application.
CHARACTER (LEN = LONG_STRING_LENGTH) :: str
CHARACTER (LEN = TOK_LENGTH) :: tok
REAL (KIND = DP) :: dd
REAL (KIND = SP) :: rr
INTEGER :: ii
INTEGER :: errorCode
errorCode = 0
READ(fid,*,iostat = errorCode) str
IF (errorCode .NE. 0) GOTO 99
CALL NextString(str,tok,errorCode)
IF (errorCode .NE. 0) GOTO 99
CALL NextDouble(str,dd,errorCode)
IF (errorCode .NE. 0) GOTO 99
CALL NextReal(str,rr,errorCode)
IF (errorCode .NE. 0) GOTO 99
CALL NextInteger(str,ii,errorCode)
IF (errorCode .NE. 0) GOTO 99
99 CONTINUE
IF (errorCode .NE. 0) THEN
CALL ProcessError()
END IF
On 10/02/2011 7:28 PM, Mudelsee M wrote:
> Hi all,
>
> it is interesting to watch the discussion, thanks.
>
> The purpose of my request (copied below) was to become able to produce
> a more user-friendly software product: the program should just not
> terminate if "just" a letter (i.e., instead of a number) was wrongly
> typed in for a real or integer variable input, the user would be given
> ntry chances, with ntry in the order of 5.
>
> However, the software should detect if something has been wrongly
> typed in.
>
> I am surprised that at least one compiler (Absoft) has problems with
> that. I checked the code (below) with gfortran-compilation:
>
> q (ioerr .ne. 0)
> e (ioerr .ne. 0)
> / (a unchanged)
> i (proceeded one line, upon seemingly any next input iorr .ne. 0)
> d (ioerr .ne. 0)
> n (proceeded one line, upon seemingly any next input iorr .ne. 0)
>
> gfortran seemed in this respect to behave better (more "ioerr .ne. 0")
> than Absoft.
>
> I am too lazy to complain to the compilor makers, but some of them
> perhaps subscribe to our newsgroup!?
>
> Best
>
> Manfred
>
>
>
>
> Am 10.02.2011 07:29, schrieb Malcolm Cohen:
>>> A program is a standard-conforming program if it uses only those
>>> forms and relationships described herein and if the program has
>>> an interpretation according to this part of ISO/IEC 1539.
>>>
>>> So,
>>>
>>> READ(*,*) A
>>> WRITE(*,*) A
>>> END
>>>
>>> we usually say this program is standard-conforming.
>>
>> Yes, and it is given valid input data.
>>
>>> But if we
>>> depend on this program to, say, abort with an error message for a
>>> non-numeric input value, this program is not standard-conforming??
>>
>> Correct. The standard does not give the program an interpretation when
>> it is applied to invalid data.
>>
>> If the input data is the record
>> FRED
>> then it does not satisfy the standard which says (page 263, 10.10.3
>> paragraph 1 sentence 2):
>> "The form of the input value shall be acceptable for the type of the
>> next effective item in the list."
>>
>> "shall" is a requirement. "FRED" is not an acceptable form for REAL A.
>> End of story.
>>
>> One can write programs that don't violate the standard for invalid
>> input, by having the program do input validation itself (i.e. by reading
>> it into a CHARACTER variable and checking the format). Admittedly that
>> is pretty tedious so people rarely bother, either because they "know"
>> that their input is valid, or because they trust the compiler to
>> generate a nice error code for them. And most compilers do... but in
>> fact it is not required.
>>
>> Cheers,
>
> original request:
>
> ===
>
> Dear all,
>
> I was puzzled by the behaviour of the Fortran 90 code below (compiled
> with AbSoft 10.0, Windows XP machines, keyboard language German): the
> executable took without complaining (i.e., ioerr = 0) following inputs
> of mine at the read statement for the real variable and reset the a
> values (in parentheses as follows:
> q (a = 0)
> e (a = 0)
> / (a unchanged)
> i (a = INF)
> d (a = 0)
> n (a = NaN)
>
> (Putting in ordinary stuff like numbers worked (ioerr .ne. 0) of
> course, while putting in other unordinary stuff like $ worked not.
>
> I have the feeling that all this is not a compilor error but a well
> known Fortran behaviour since the 1960s, some old-fashioned
> convention. Anyway, I would highly appreciate if someone could
> enlighten me in that respect. Many thanks!
>
> Manfred
>
>
> ===
>
>
> program test
> integer :: i
> integer :: ioerr
> real :: a = -999.0
> print *, a
> do i=1,100
> print *, 'Input new value: '
> read (unit=5, fmt=*, iostat=ioerr) a
> print *, ' ioerr = ',ioerr,' a = ',a
> end do
> end program test
>
>
>
> ===
>
>
>
>
>
>
>
>
|