Silverfrost Forums

Welcome to our forums

Input read error

19 Apr 2007 4:27 #1872

The short program below is abbreviated from a fixed format read routine from a program that was written many years ago but is still used regularly.

  PROGRAM READCARD

  CHARACTER*80 CARD,CODE1*1,CENDR*3,CW2*2
  CHARACTER    CFORM1*26,CFORM2*29
  DIMENSION    XP(3),XI(3)

  CFORM1=   '(A1,A3,A2,I4,I5,I5,6F10.0)'
  CFORM2='(1X,A1,A3,A2,I4,I5,I5,6F10.3)'

  OPEN(16,FILE='CARD.DAT')
  OPEN(17,FILE='CARD.OUT')

C READ CARD READ(16,1020,END=9999)CARD 1020 FORMAT(A)

C READ AS NODE READ(CARD,CFORM1,ERR=35)CODE1,CENDR,CW2,NODE,NUMN,NODEIN,XP,XI

C CARD ECHO WRITE(17,CFORM2)CODE1,CENDR,CW2,NODE,NUMN,NODEIN,XP,XI GOTO 9999

35 WRITE(17,1001) 1001 FORMAT('DATA ERROR')

9999 STOP END

When the input line is 019004 -200.975 -150.0 -300.0

The program correctly writes 'DATA ERROR'. Note that the value -200.975 is in the ‘wrong’ columns. (How do I use a fixed width font here?)

When the value -150.0 is replaced by an integer -150, the program writes 019004 0 0 -200.970 0.000 -300.000 0.000 0.000 0.000

Not only does it read 0.000 incorrectly, it appears to set an error flag somewhere not related to this routine at all, so that we later get a Floating Point Overflow error. (I tried to paste the error message here but it doesn't work).

Richard May

20 Apr 2007 10:36 #1874

I do not understand the problem. The result of the first input is

CODE1 = '0' CENDR = '190' CW2 = '04 NODE = -20 NUMN is undefined because of a data error.

It seems to me that the data should contain either extra text and/or some integers.

20 Apr 2007 11:25 #1875

Paul,

This really needs a fixed width font; I'll use _ for spaces. The 1st input line is 019004_________-200.975___-150.0____-300.0 This results in CODE1 = '' CENDR = '' CW2 = '01' NODE = 9004 NUMN = 0 NODEIN = 0 XP = -200.97,5_-150.0,-300.0

The spaces in the 2nd element of XP lead to the error message, which is correct.

The 2nd input line is 019004_________-200.975_____-150____-300.0

which leads to XP = -200.97,5___-150,-300.0

and the 2nd element is interpreted as 0.0 with a spurious error flag.

Richard May

23 Apr 2007 7:33 #1876

I still do not see the problem.

You need 20 columns for the characters and integers then start at column 21 with 6 real values of width 10, i.e. at positions 21, 31, 41....

Seems to work OK.

23 Apr 2007 10:47 #1877

Yes, that is what the input should be. BUT, there are errors in the input.

  1. The value -200.975, which should be in columns 21-30, is actually in columns 24-31, i.e. it spills over to the next field.
  2. In the 2nd input line the real value -150.0 has been truncated to an integer, -150.

When -150.0 is a real, the program give an error message as expected. When -150 is an integer it does not.

If you still can't see it then I'll have to send you my program + the two data files.

23 Apr 2007 3:20 #1878

OK I now now understand the problem. We will investigate the failure to give an error report.

25 Apr 2007 8:10 #1879

Hi Richard,

The output from your program appears correct to me.

With your input of 019004 -200.975 -150 -300.0 you have -200.97 in the first floating point field and 5 -150 in the second. The blanks are ignored and the -150 is treated as an exponent (as specified by the fortran standard).

This gives you a very small number (5E-150) - so small that when you try and store it in your single precision real you get a floating point underflow as the smallest positive number a floating point real can store is 1E-38. the underflow is ignored by default, but if you compile with the /underflow command line option the floating point underflow will be reported as an error. The stack trace should report the error occuring within the runtime library, with your routine further down.

25 Apr 2007 8:10 #1880

By the way, you can display text in a fixed width font in this forum by placing it within the [code][/code] tags as I did in my previous post.

26 Apr 2007 1:04 #1881

Thanks. I didn't know the Fortran standard treated 5 -150 as an exponent. We will have to trap this type of input error ourselves. The stack trace did not mention the routine where this data was read, it indicated a completely different part of the program.

1 May 2007 1:23 #1883

I have recently encountered this problem, where the E in the exponent is omitted. This was the first time in over 33 years of using fortran. Values such as '1.234-05' being used as a semi compressed form of '1.234e-05' for coordinates. I have not tried to select this format in a write statement and it can become an annoyance, as other packages, such as Excel, do not recognise the format. I was not aware that '1.234___-05' was also allowable, which is hardly compressed. Does anyone know the history of this compressed scientific notation in fortran ? Shouldn't the embedded blanks be an error ? It would certainly be better if it was, as in most cases scientific notation would not be what is intended.

regards John

1 May 2007 6:50 #1884

The compressed form 1.234-05 is listed in the Fortran standard. The possible inclusion of blanks is not mentioned so must be considered as a FTN95 extension to the standard.

The extension is probably not trapped by using /ISO on the FTN95 command line but I guess we could see if this might be easy to implement. As always we have to be careful not to break existing software.

3 May 2007 3:22 #1886

Paul,

The valid use of blanks is a difficult one, as the following code may show. It might be valid to include blanks to separate 000's in large integers and using either (I12) or (BN,I12) formats this does work. I've certainly never used this but it may be a valid form. It's a better alternative to the European '.' separator or the American ',', but it's a bit late to start something new.

I would doubt that strings like '1.05 -5' would be intended. It looks more like a data error to me, but there are a lot of different interpretations out there !

! test of blanks in a number ! character number_string12 integer4 num, iostat ! number_string = ' 1 000 000 ' read (number_string,fmt='(i12)', iostat=iostat) num write (,) 'I12 read gives', num, iostat ! read (number_string,fmt='(bn,i12)', iostat=iostat) num write (,) 'bn,I12 read gives', num, iostat ! read (number_string,fmt='(bz,i12)', iostat=iostat) num write (,) 'bz,I12 read gives', num, iostat ! end

This program gives:

[FTN95/Win32 Ver. 4.9.1 Copyright (c) Silverforst Ltd 1993-2006]

NO ERRORS  [<main program> FTN95/Win32 v4.9.1]

Creating executable: C:\temp\test\lgotemp@.exe Program entered I12 read gives 1000000 0 bn,I12 read gives 1000000 0 bz,I12 read gives 1000000000 0

3 May 2007 10:30 #1895

I think FTN95 complies with the standard regarding the inclusion of (non-leading) blanks in a numerical input field, including when using the F edit descriptor.

The standard says there is a blank interpretation mode which can either be NULL or ZERO. When it is NULL blanks are ignored. When it is ZERO blanks are treated as 0's. The OPEN statement has a BLANK= specifier for setting this mode, which defaults to NULL if not present. Data transfer statements can also have a BLANK= specifier to override the current blank interpretation mode for that statement. The BN and BZ format edit descriptors also temporarily change the mode.

Please login to reply.