Fortran routine skips lines but is not allowed to. - fortran

I made a Fortan routine to read a weather file into my program. This file contains 2 header lines and then lines of data for every 10 minutes and is therefor 52562 lines long.
When reading the file with the code below it returns the error Fortran runtime error: End of file for i = 52548 in the do-loop.
bdst=600
allocate(clidat(int(3.1536d7/bdst),15))
open(2001,file='church_10m.cli',action='read')
read(2001,*); read(2001,*)
do i=1,size(clidat,1)
read(2001,*) clidat(i,:)
enddo
close(2001);
The file used can be found using this public dropbox link: church_10m.cli. I checked and the file does contain the 52562 lines. The line corresponding to i = 52548 is the last line of the file. The line corresponding to i=1 is the third line of the file (which starts with 0). So I suspect that some lines are skipped in between. Any thoughts why this happens?

If a line doesn't contain 15 values (the size of clidat) the read statement just goes to the next line and reads the next values. There were a couple of lines in the church_10m.cli file that didn't have enough values. (for example line 1957).
This was a result of the conversion from an excel file to a txt file.

Related

Problem with writing .dat files using Fortran

I am reading a .txt file and writing to a .dat file for use in GrADS.
The .txt file contains 1D data, and my program reads all 123 lines correctly as I checked by printing on screen. However, the result .dat file only contains the very first line of data, the rest are all zeros. How can I fix this? Did I set the dimensions in write incorrectly?
Here is my code:
program convert
integer,parameter::nlon=1,nlat=1,nz=123
real,dimension(nlat,nlon,nz)::pr
integer::ilon,ilat,iz
open(2,file='2020082100_1.txt',form='formatted',status='old')
INQUIRE(IOLENGTH=LREC) pr
open(3,file='2020082100_1.dat',form='unformatted', &
access='direct',recl=LREC)
do iz=1,nz
do ilat=nlat,1,-1
read(2,*) (pr(ilat,ilon,iz),ilon=1,1)
end do
end do
IREC=1
do iz=1,nz
write(3,rec=irec) ((pr(ilat,ilon,iz),ilon=1,nlon),ilat=1,nlat)
IREC=IREC+1
end do
close(2)
close(3)
end program convert
For example, the first few lines of the .txt file are:
30.7
29.4
25.9
24.2
24.4
...
However, the .dat file contains this:
30.7
0
0
0
0
...
So after tinkering with the code for a few hours, I figured out how to fix it myself.
Since all the data is writing on the wrong axis, I simply need to change a single line of code:
from this:write(3,rec=irec) ((pr(ilat,ilon,iz),ilon=1,nlon),ilat=1,nlat)
to this: write(3,rec=iz) ((pr(iz,ilon,ilat),ilon=1,nlon),ilat=1,nlat).
By changing this it completely worked. I did actually set the dimensions in write incorrectly.

How to determine file size in Fortran 77

I have a Fortran program that needs to read ASCII files, however the list of files sometimes includes a file of size 0. The program then crashes when trying to read this file. I have not find any way so far that will allow me to flag such a file.
I have following READ statement in my code
read(10,220,END=320,ERR=195)parm(1:)
although I expect code to go to statement 195, or to statement 320, without crashing, it crashes
this is where the code crashes when the file size is zero, with the following messages
...
fmt: end of file
apparent state: unit 10 named junko.con
last format: (A)
lately reading sequential formatted external IO
I tried using the INQUIRE statement
inquire (unit=10,SIZE=nsize), but the program would not compile
the OPEN statement did not give any error when opening the zero size file, and the values of IOSTAT was the same, irrespective of the file size
As Ian noted, any modern Fortran compiler should have INQUIRE. A simple test of
program foo
integer sz
inquire(file='tmp.dat',size=sz)
print *, sz
end program foo
with an empty tmp.dat file sets sz=0.

Unable to read a number from a text file

I am using Fortran to make a subroutine to use in a CFD shallow water software.
I have written this code to read and use the values stored.
PROGRAM hieto
! Calcula la precipitacion efectiva en funcion del tiempo
!IMPLICIT NONE
real::a
!Abrir CSV
!OPEN(UNIT=10,FILE="datos.txt",FORM="formatted",STATUS="replace",ACTION="readwrite",ACCESS='sequential')
open(unit=10, file='datos.txt')
!Leer el archivo
read(10, *, iostat=ios)a
print*,ios
print*, a
close (UNIT=10)
END PROGRAM hieto
My text file datos, looks like this
1
2
3
When I run the code as is, I get the following output
-1
0.0000000000
Process return 0 (0x0) execution time: 0.002 s
the first number in the row one is one not zero, so I don't know why this happens.
And if I remove the iostat=ios from the read statement, I get the following error:
At ine 13 (the line od the read stament) of file /home/Dropbox/scripts_tesis/fortran/hieto_telemac.f90 (unit=10, file=datos.txt')
Fortran runtime error: end of file.
Proceess returned 2 (0x2)
I have read some answers here so I tried adding end=3 in the read statement, and also to end my text file with a blank line at the end.
The end=3 gives an error saying 3 is not a defined label and putting a blank row in the text file does nothing.
I am using ubuntu 16.04 LTS and Gfortran compiler.
What happens is that your file is empty.
Make sure that there is indeed a file called datos.txt in that directory. Pay attention to the exact name. datos.txt and just datos is not the same thing.
If you tried to open it before with the commented command that includes STATUS="replace" your old file would have been replaced.
And because the file is empty, you didn't real anything useful. If iostat is non-zero, and your is -1, then the value of the variable being read is undefined. So your a is undefined. Again, because your file is empty.
Additionally, you cannot just blindly put end=3 in your code because you saw it somewhere on Stack Overflow. You must first understand what it is supposed to do. There is no reason to combine iostat= and end=. The iostat is perfectly sufficient.

Unexpected end of file with the read command

I'm trying to read data from a mesh file in Fortran 2003, but I'm getting an unexpected end of file runtime error. Some lines in the file seem to be skipped by the read command. For example, with this sample.txt file :
1 2 2 0 1 1132 1131 1165
2 2 2 0 2 1099 1061 1060
I want to read the first integer from each line, so my program is :
program read_file
implicit none
integer :: ierr, i, j
open(unit=10,file='sample.txt',status='old',action='read',iostat=ierr)
read(10,*) i
read(10,*) j
write(*,*) i, j
end program read_file
And at runtime, I'm getting
Fortran runtime error: End of file
What is odd is that if I force a carriage return at the end of the file, the program will read the two integers just fine.
If you really need to fix this on the read side (ie. properly terminating the last line of the file is not practical for some reason ) you might try reading each line into a string, then internal reading from the string:
character*80 line
integer i
do ..
read(unit,'(a)')line
read(line,*)i
enddo
Of course this may or may not work depending on the compiler as well..
Obviously fixing the file is the best option ( Whatever program is creating this file should be fixed )
Every record in a sequential file must be properly terminated. The records in text files are the lines. They must be properly terminated. In some editors that means you must add an empty line to the end. Every line containing data must be terminated.
Some compilers are less sensitive to this issue than others and will terminate the last record for you.

C++ reading text file line by line stops partway through

I have a file with 16,900,000 lines, each line contains 10 numbers (mix of int and floats). I'm trying to read this file line by line, modify each line slightly, and write to a series of new files. The code below works on a laptop running Windows Visa, but when I run it on a desktop running Windows 7, the output file does not contain all the data from the input file. The number of lines in the output file varies from 2500 to 40,000.
I've commented out all of the processing, and writing to files, and just write every 100th line to cout, the last line to print isn't the last line of the file.
// skipping code prior to the loop
// only including minimal code that reproduces the problem
ifstream infile((srcdir+filename).c_str());
string line;
int lcount=0;
while(getline(infile,line)){
if(line.find("#")==string::npos){
lcount++;
if(lcount%100==0){
printf("Generating tiles for %s: %d lines processed\n",filename.c_str(),lcount);
}
}
}
Questions:
Is there a maximum buffer size that I might be overflowing?
Can anyone see a problem with my code?
Is there any reason this would work fine on Windows Vista, but not on Windows 7?
In your question there is very little information. But I will put here my guesses:
I don't think lcount is in being incremented at the correct place in code. It get incremented only if '#' is not in the line (I'm guessing this is some sort of comment). But a line starting (o containing) '#' has to be counted too. So your code should be:
while(getline(infile,line)){
lcount++; // Increment every time.
if(line.find("#")==string::npos){
if(lcount%100==0){
printf("Generating tiles for %s: %d lines processed\n",filename.c_str(),lcount);
}
}
}
On the other hand, you should activate isftream exceptions in order to see whats going on, see here how to doit.
While trying to create a minimal full program that would reproduce the problem, I found the culprit.
I'm trying to secure the executable with the keylock dongle that my company is using. When I removed the check for the dongle, the entire file was read.