I am writing a Fortran program to read data from 35 files with similar size(8 columns and 8784 lines in each file) and write to a single file. I wrote the following code and when compiling "Invalid or missing repeat count" error is appearing.
Program Basic
implicit none
Character*20,dimension(35)::filename(/'1979.txt','1980.txt','1981.txt','1982.txt','1983.txt','1984.txt','1985.txt','1986.txt','1987.txt','1988.txt','1989.txt','1990.txt','1991.txt','1992.txt','1993.txt','1994.txt','1995.txt','1996.txt','1997.txt','1998.txt','1999.txt','2000.txt','2001.txt','2002.txt','2003.txt','2004.txt','2005.txt','2006.txt','2007.txt','2008.txt','2009.txt','2010.txt','2011.txt','2012.txt','2013.txt'/)
real,dimension(1:8784)::Db,Dp,WS
integer,dimension(1:8784)::a,b,c,d,SR
integer::i,file
do file=1,35
open(7000,file=filename(file))
open(7001,file='Final.txt')
do i=1,8784
read(7000,*)a(i),b(i),c(i),d(i),Db(i),Dp(i),WS(i),SR(i)
write(7001,*)a(i),b(i),c(i),d(i),Db(i),Dp(i),WS(i),SR(i)
end do
end do
end Program Basic
The output from the compiler (Silverfrost FTN95) is
Runtime error from program:c:\users\aadhikari2\desktop\trial 1\freeformat1.exe
Run-time Error *** Error 62, Invalid or missing repeat count BASIC - in file freeformat1.f95 at line 19 [+0325]
The declaration line
Character*20,dimension(35)::filename(...
is too long for free form Fortran (see Line truncated, Syntax error in argument list ). You must split the line.
But also the array declaration is not syntactically correct. You should use the = assignment as in
Character*20,dimension(35) :: filename = (/'1979.txt','1980.txt','1981.txt', &
'1982.txt','1983.txt','1984.txt', &
'1985.txt','1986.txt','1987.txt', &
'1988.txt','1989.txt','1990.txt', &
'1991.txt','1992.txt','1993.txt', &
'1994.txt','1995.txt','1996.txt', &
'1997.txt','1998.txt','1999.txt', &
'2000.txt','2001.txt','2002.txt', &
'2003.txt','2004.txt','2005.txt', &
'2006.txt','2007.txt','2008.txt', &
'2009.txt','2010.txt','2011.txt', &
'2012.txt','2013.txt'/)
Also, don't forget to close your files at the end.
Related
I am trying to execute a Fortran code and I get the following error:
At line 215 of file prepmegan4cmaq_grwform.f90
Fortran runtime error: Bad value during floating point read
And this is how the line 215 of my .f90 file looks like:
read(shrubfillvalue,"(f7.0)") missing_value
I do not have any experience with Fortran coding, can someone please tell me what it means and how I can fix this problem.
Thank you in advance
This error is telling you that the text it tried to read did not meet the rules for a numeric value. The code itself is fine, the error is in the input (which you did not show).
The F7.0 format will accept seven characters that are valid as a number, for example: -1234.5, 2478bbb, 3.15E24, etc. (where "b" means blank). So, look at the input file and see what is in that line.
It is possible that the program is reading the wrong line from the file after having read an incorrect number of lines previously.
I have also been running the latest version of MEGANv3.2, and found this to be an issue with reading missing_value attribute in 3 out of 4 of the input files provided by the MEGAN team.
Since all of the missing_value attributes are the same between the four different files (i.e., -128), a very quick work around is to simply change the prepmegan4cmaq_grwform.f90 code to read only the treefillvalue for each of the four datasets:
!-----read growth form----------------------------------------------
scale_factor = 1.
inpname = trim(treefilename)
varname = trim(treevarname)
!missing_value = -1.
read(treefillvalue,"(f7.0)") missing_value
CALL megan2_bioemiss
inpname = trim(shrubfilename)
varname = trim(shrubvarname)
! read(shrubfillvalue,"(f7.0)") missing_value
read(treefillvalue,"(f7.0)") missing_value
CALL megan2_bioemiss
inpname = trim(cropfilename)
varname = trim(cropvarname)
! read(cropfillvalue,"(f7.0)") missing_value
read(treefillvalue,"(f7.0)") missing_value
CALL megan2_bioemiss
inpname = trim(grassfilename)
varname = trim(grassvarname)
! read(grassfillvalue,"(f7.0)") missing_value
read(treefillvalue,"(f7.0)") missing_value
CALL megan2_bioemiss
! endif
And then simply recompile the prepmegan4cmaq_grwform.f90 code. Hope this helps.
I would like to read the same line of a file many time in Fortran. The concerned data are real values. I tried to build this code as test but I am always getting it wrong.
program advance
implicit none
integer , parameter :: ut = 20
character(len=7) :: fname = 'dat.dat'
integer :: n, idx
character(len=100) :: lnumber
open(unit = ut, file =fname, status='old', action='read')
n = 10
do idx = 1, n
read(ut, '(a)', advance = 'no') lnumber
print *, lnumber
end do
end program advance
The dat.dat file contains one line with 25.325654515464564564
The code return the following error.
At line 13 of file advance.f90 (unit = 20, file = 'dat.dat')
Fortran runtime error: End of record
How do I fix this bug?
Such non-advancing input (using advance='no') doesn't mean that the file position is not advanced at all. It means that the file position isn't advanced beyond what is needed to satisfy the requirements of the input list.
So, in this case, the file position is advanced by reading the single "real number" into the character variable lnumber. The next read will continue from this later point. This later point happens to be the end of the file.
With advancing input more generally, the file position is advanced to the start of the next record even if the record is not required in entirety.
As High Performance Mark comments, reading the same line over and over again likely isn't what you should be doing. You could read the line into a character variable (such as is done here) and repeatedly use that variable as an internal file. However, if you really want to read a line again, consider backspace.
I have a sub routine file as follows
subroutine grids(Ngrids,gridsize,boundx,boundy,boundz,occmatrix,myid)
implicit NONE
integer i,j,k,Ngrids, occmatrix(14,14,10)
integer locx,locy,locz,myid
double precision gridsize,boundx,boundy,boundz
do i = 1, 14
do j = 1, 14
do k = 1, 10
occmatrix(i,j,k) = 0
enddo
enddo
enddo
open (13, file = 'grid_data.9deg')
write(*,'(A,i2)'),' READING GRID FILE ON PROC.....',myid
read(13,*) Ngrids,gridsize
read(13,*) boundx,boundy,boundz
do i = 1, Ngrids
read(13,*) locx, locy, locz
occmatrix(locx,locy,locz) = 1
enddo
close(13)
return
end
It gives the following syntax error in compiling
subroutine grids(Ngrids,gridsize,boundx,boundy,boundz,occmatrix,my
1
Error: Unexpected junk in formal argument list at (1)
It used to run well before
I would believe, your line is to long. Did you add a new argument? Your code looks like free form, but it might be the compiler tried to apply fixed form due to a .f suffix in the filename or something like that. Convince the compiler to assume free formatted source code (by compiler options or usually a .f90 suffix).
Even in free formatted files your line width is limited and you should break longer lines, which would for example look like:
subroutine grids( Ngrids,gridsize,boundx,boundy,boundz, &
& occmatrix,myid )
If you are stuck with fixed format you need to indicate a continuation line by a non blank character in column 6.
Here is how it looks like in fixed form:
subroutine grids(Ngrids,gridsize,boundx,boundy,boundz,
& occmatrix,myid)
Please do not use fixed form anymore! Instead, change your files to end with .f90, most compilers recognize this for free formatted code.
I am receiving a formatting error from an input file, and I would like to determine where the formatting error is occurring in the input file.
My question is: Is there a way to print the line number of the input file where the error is occurring in my fortran code?
This is the error I get:
fmt: read unexpected character
apparent state: unit 4 named input_file
last format: (6(I3,X,F7.2,X,I2,X))
lately reading sequential formatted external IO
Which means that the code is getting hung up on some line in my input file that doesn't correspond with the above format.
Here is the part of my code where Fortran is reading in the input file:
DO 20 K = 1,NUMB
READ(4,200) (NSTN(J),TT(J),IKPS(J),J=1,6)
DO 30 J = 1,6
L = L+1
ISTO(L,N) = NSTN(J)
SECT(L,N) = TT(J)
KWV(L,N) = IKPS(J)
30 CONTINUE
20 CONTINUE
KOBS(N) = NSTM
10 CONTINUE
100 FORMAT(5(I2,X),F6.2,X,F5.2,X,F7.3,X,F6.3,X,F8.3,X,F6.3,
& X,F6.2,X,F5.2,X,I3,X,F4.1,X,F5.2,X,F7.3)
200 FORMAT(6(I3,X,F7.2,X,I2,X))
RETURN
END
I'd like to add a line in the above piece of code to identify the current line the code is reading, so that when it gets hung up, I'll know which line contains the error. Thank you for your help.
Here's what I tried and it's giving me another error:
c READ(4,200) (NSTN(J),TT(J),IKPS(J),J=1,6)
READ(4,200)line
READ(line,*,iostat=ios) (NSTN(J),TT(J),IKPS(J),J=1,6)
IF(ios>0)THEN
WRITE(*,*)'Error Reading Line',line
STOP
ENDIF
INTEGER ios
CHARACTER*(200)line
With a read statement like
READ(4,200) (NSTN(J),TT(J),IKPS(J),J=1,6)
an error in the input results in (error) termination of the program. One has no control over this termination, and in particular one can't do further processing.
There are two ways to avoid this termination, and both involve using an additional specifier in the read statement. One is iostat= and the other err=. If either of these is present then an error doesn't result in termination.
With iostat (for integer istat):
READ(4,200,iostat=istat) (NSTN(J),TT(J),IKPS(J),J=1,6)
then on an error condition, istat will have a (processor-dependent) positive value. It will be zero when (and only when) there is no error.
With err (for some label, say, 991):
READ(4,200,err=991) (NSTN(J),TT(J),IKPS(J),J=1,6)
Putting all that together, let's imagine an outer loop
DO 100 LINE=1,91959
READ(4,200,IOSTAT=ISTAT) (NSTN(J),TT(J),IKPS(J),J=1,6)
IF (ISTAT.NE.0) THEN
PRINT *, 'It went wrong on line', LINE
STOP
END IF
...
100 CONTINUE
or
DO 100 LINE=1,91959
READ(4,200,ERR=991) (NSTN(J),TT(J),IKPS(J),J=1,6)
...
100 CONTINUE
...
991 PRINT *, 'It went wrong on line', LINE
STOP
[I couldn't bring myself to write that code like it really was 1980.]
Add an explicit loop to read your data like:
DO 20 J = 1,6
write (*,*) 'Reading line = ', J
READ(4,100) NSTN(J),TT(J),IKPS(J)
20 CONTINUE
100 FORMAT(I3,X,F7.2,X,I2,X)
This way, you will know exactly where it stopped thank to the write statement in the reading loop. Note that I added two new labels, 20 to control the new loop and 100 for the new format statement. Adapt accordingly.
==============
DO 20 K = 1,NUMB
WRITE (*,*) 'Reading line = ', K
READ(4,200) (NSTN(J),TT(J),IKPS(J),J=1,6)
DO 30 J = 1,6
L = L+1
ISTO(L,N) = NSTN(J)
SECT(L,N) = TT(J)
KWV(L,N) = IKPS(J)
30 CONTINUE
20 CONTINUE
KOBS(N) = NSTM
200 FORMAT(6(I3,X,F7.2,X,I2,X))
RETURN
END
I have some issues about opening and reading multiple files. I have to write a code which reads two columns in n files formatted in the same way (they are different only for the values...). Before this, I open another input file and an output file in which I will write my results. I read other questions in this forum (such as this one) and tried to do the same thing, but I receive these errors:
read(fileinp,'(I5)') i-49
1
devstan.f90:20.24:
fileLoop : do i = 50,52
2
Error: Variable 'i' at (1) cannot be redefined inside loop beginning at (2)
and
read(fileinp,'(I5)') i-49
1
Error: Invalid character in name at (1)
My files are numbered from 1 to n and are named 'lin*27-n.dat' (where n is the index starts from 1) and the code is:
program deviation
implicit none
character(len=15) :: filein,fileout,fileinp
integer :: row,i,h
real :: usv,usf,tsv,tsf,diff
write(*,'(2x,''Input file .......''/)')
read(*,'(a12)') filein
write(*,'(2x,''Output file........''/)')
read(*,'(a12)') fileout
open(unit = 30,File=filein)
open(unit = 20,File=fileout)
fileLoop : do i = 50,52
fileinp = 'lin*27-'
read(fileinp,'(I5)') i-49
open(unit = i,File=fileinp)
do row = 1,24
read(30,*) h,usv,tsv
read(i,*) h,usf,tsf
diff = usf - usv
write(20,*) diff
enddo
close(i)
enddo fileLoop
end program deviation
How can I solve it? I am not pro in Fortran, so please don't use difficult language, thanks.
The troublesome line is
read(fileinp,'(I5)') i-49
You surely mean to do a write (as in the example linked): this read statement attempts to read from the variable fileinp rather than writing to it.
That said, simply replacing with write is probably not what you need either. This will ignore the previous line
fileinp = 'lin*27-'
merely setting to, in turn, "1", "2", "3" (with leading blanks). Something like (assuming you intend that * to be there)
write(fileinp, '("lin*27-",I1)') i-49
Note also the use of I1 in the format, rather than I5: one may want to avoid blanks in the filename. [This is suitable when there is exactly one digit; look up Iw.m and I0 when generalizing.]