- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When the below command executes, it read the file content ( 35) where all the spaces are ignored and it reads only the numbers in that case the size of the number is only 2 bytes, but we are trying to read 8 byte number which throws the exception.
FORMAT(I8)
IF I use FORMAT(I2) then there is no exception
program test
INTEGER(4) IRATE
OPEN(4,file='C:\Srini\Files\Arat51',status='OLD',access='DIRECT',
& form='FORMATTED',recl=8)
Read(4,200,rec=2)IRATE
CLOSE(4)
200 FORMAT(I8)
STOP
end
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
With your data file, the following program works correctly if I specify RECL=10 in the OPEN statement, with the data file containing CR+LF at end-of-line. Similarly, with the datafile using LF for EOL, using RECL=9 in the OPEN statement gives correct output.
program test INTEGER(4) IRATE,i ! OPEN(4,file='Arat51',status='OLD',access='DIRECT', & form='FORMATTED',recl=10) i=2 DO while(i .le.16) Read(4,200,rec=i)IRATE write(*,*)i,irate i=i*2 end do CLOSE(4) 200 FORMAT(I8) STOP end
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Using _formatted_ direct access files is rather unusual. (Most of the time direct access files are unformatted, that is, raw bytes are stored, not human-readable numbers). As you set the record length to 8, it may be that the last one or two positions in these records are actually reserved for carriage-return/linefeed characters. This means that you format is simply too wide. Using a format I2 instead of I8 means that the read action stays well within the record and can therefore proceed.
What is the reason for using this kind of files? There may very well be an easier-to-use alternative. For instance: simply a sequential file.
What is the error message you get?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The file content looks like,
131072
35
35
852
916
986
1064
979
989
999
1011
1023
1037
1051
0
0
0
0
0
The error we get for this is forrtl: severe (64): input conversion error
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You could try reading it like this:
integer :: ierr open( 4, file = '... proper name ...' ) do read( 4, *, iostat = ierr ) irate if ( ierr /= 0 ) exit enddo close( 4 )
So rather than opening it as a direct access, use the default. Instead of a specific format, use list-directed reads (the *). While it is not completely safe (see below), it is more flexible and as you open it as a sequential file, the lines may be any length.
(Safety of list-directed reading: a list-directed read will read on until all items in the read statement could be read or an error occurred. There are a few more rules that might bite you, although I have seldom seen them in practice. If you really need to read the file line by line, then use :
character(len=10) :: line read( 4, '(a)', iostat = ierr ) line read( line, * ) irate
with appropriate changes to fit in the code above)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The read statement in real time code will be like READ(4,200,rec=IPOS)IRATE, where IPOS will have the line number from where the data needs to be taken from file.
so I cant change the existing logic..:(
The same code works well in win Xp Compaq visual Fortran compiler but in Win 7 Intel visual Fortran its throws the error.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I tried this in a small program: using a file with records of numbers like 12345678.
When I open the file with a record-length of 8, then the first record is read correctly, but the second causes an input conversion error.
However, if I open the file with record-length 10 (to explicitly include the carriage-return/linefeed bytes), it works fine. My guess is therefore that Compaq Fortran automatically corrected for the extra bytes and that Intel Fortran does not. (The record-length of 10 bytes works fine with gfortran too)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The below code works fine but it reads the first line, how can I make it as by entering the line number ti should read
{code}
character(len=10) :: line read( 4, '(a)', iostat = ierr ) line read( line, * ) irate
{code}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
See my other answer - you seem to require genuine direct access. I think the record length is wrong
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The below command fails but if I use rec=1 no error the first line executes..
read( 4, '(a)',rec=3, iostat = ierr ) line
I am new Fortran please help..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I understand that you are new to Fortran, but it would help if you provide enough information:
- How does it fail? What is the error message?
- How do you open the file?
- Better still: Can you post the complete program?
Note my previous post - about the record length - my guess is that it should be 10 not 8.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
With your data file, the following program works correctly if I specify RECL=10 in the OPEN statement, with the data file containing CR+LF at end-of-line. Similarly, with the datafile using LF for EOL, using RECL=9 in the OPEN statement gives correct output.
program test INTEGER(4) IRATE,i ! OPEN(4,file='Arat51',status='OLD',access='DIRECT', & form='FORMATTED',recl=10) i=2 DO while(i .le.16) Read(4,200,rec=i)IRATE write(*,*)i,irate i=i*2 end do CLOSE(4) 200 FORMAT(I8) STOP end
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you very much.. by changing the recl value to 10 (recl=10) the code worked without any exception...
Will implement the same in the live code..
but can you guide what is the use for recl? why do we need to change it to 10?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
One explanation is that the value specified with RECL= is used to map record number to the byte offset in the file. Since Windows and Unix have a simple notion of a file as a collection of bytes, the old mainframe record-oriented file types have to be simulated.
Thus, if you have a file with 8 characters per line, and CR+LF as end-of-line, Rec-1 is at byte 0, Rec-2 is at byte 10,..., and Rec-n is at byte (n-1)*10.
There is a keyword to help with record sizes; use an IOLENGTH= clause in an INQUIRE statement on the file.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Therese was one more error in another file,
program test2
INTEGER(4) IPOS
INTEGER*4 TBDATE(3),IEFFDT
DIMENSION ITB(0:3)
INTEGER IYEVT,IMEVT,IENTRY,ITERM
integer :: ierr
OPEN(4,file='File1',status='OLD',SHARE='denywr',
& access='DIRECT',form='FORMATTED',recl=48)
READ(4,900,REC=1557)IPOS,IEFFDT,IYEVT,IMEVT,IENTRY,ITERM,
& (ITB(I),I=0,3)
CLOSE(4)
900 FORMAT(I4,I9,I5,I2,I5,I3,4I5)
stop
end
The File content looks like,
1548 20170201 2029 8 2010 19 15 -11 15 41
1549 20170201 2029 8 2011 18 13 -12 13 37
1550 20170201 2029 8 2012 17 11 -12 11 34
1551 20170201 2029 8 2013 16 8 -13 8 30
1552 20170201 2029 8 2014 15 5 -14 5 25
1553 20170201 2029 8 2015 14 2 -15 2 19
1554 20170201 2029 8 2016 13 -2 -17 -2 12
1555 20170201 2029 8 2017 12 0 0 0 0
1556 20170201 2030 8 1985 45 28 -19 28 75
1557 20170201 2030 8 1986 44 26 -20 26 71
I tried changing the recl values but still exception is thrown
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, the problem seems to be the same thing: a mismatch between the actual length of the records in the file and the length that you specify in the program. If you carefully count the number of positions expected by the format, you get to 48. The length specified. But as before, you need to also include the invisible bytes. So use a length of 50.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I changed the length to 50 but still there is an exception.. I even changed it 80 but the same exception are thrown.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You should be aware that this is a very fragile way of working: if the length of the records in the file is not constant, it will fail, since the bytes that are read critically depend on the length that you give. Even as much as a single additional byte or a single byte not present (a space for instance) will cause problems.
It makes no sense to set the record length to, say, 80, because, unlike with sequential files, there is NO flexibility. Your record length in the program must match exactly the record length in the file. Down to the last invisible byte.
Is it possible to change the program that produces these files? For instance to have it write _unformatted_ direct-access files?
Your only hope is to examine the input file byte by byte. If - and ONLY if - every record has the same length, the method you have been using will work with that length. Here is a small Fortran program that you can use:
! chkfile.f90 -- ! Read a (text) file byte by byte and report the perceived record length ! program chkfile implicit none integer :: ierr, length, recno character(len=1) :: byte open( 10, file = 'example.inp', access = 'stream' ) recno = 0 length = 0 do read( 10, iostat = ierr ) byte if ( ierr /= 0 ) then exit endif length = length + 1 if ( byte == achar(10) ) then recno = recno + 1 write( *, '(a,i5,a,i10)' ) 'Length of record', recno, ': ', length length = 0 endif enddo endprogram
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Shrinivassan R. wrote:
I changed the length to 50 but still there is an exception.. I even changed it 80 but the same exception are thrown.
You need to know the structure of your data files precisely, if you wish to access them as fixed-record-length direct-access files. Willy-nilly changing of the RECL value in the OPEN statement will just waste time.
Here is a modified version of the code in #11 to read the data file displayed in #14:
program test INTEGER ISEQ,cdate,cyr,n,eyr,i,i3(5) ! OPEN(14,file='r48.txt',status='OLD',access='DIRECT', & form='FORMATTED',recl=50) i=2 DO while(i .le.8) Read(14,200,rec=i)iseq,cdate,cyr,n,eyr,i3 write(*,*)i,iseq,cdate,cyr,n,eyr,i3 i=i*2 end do CLOSE(14) 200 FORMAT(I4,I9,I5,I2,I5,I3,4I5) STOP end
I used a record length of 50 precisely because the data has 48 'payload' characters per line/record and I stored the file as a CR+LF text file.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks a million.. It worked:)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Something doesn't seem quite right. The user should never need to specify a record length that includes compiler added record structure content, especially for direct access (e.g. the leading and trailing length value that some compilers add to emulate fixed length records on "real" OS'). The user should only need to define the "data" content. Record structure added content should be assumed by the compiler based upon the specified open parameters.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I agree that having to add the byte count of the EOL to the record size makes me uncomfortable, too. I did spend a few minutes reading through sections of the F2003 standard to pin this issue down, but failed.
On the other hand, many record-type files are not portable (say, from ZOS to VMS or Unix), so perhaps one should not expect the standard to go into "implementation details".
Such discrepancies probably motivated the creation of HDF and CDF files.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page