Fortran runtime error - issue capturing user input


I am really not a Fortran expert and I needed some help. A request for assistance with the program at the below link (actually an old USGS program). It was sent from a researcher on on a geological mailing list - it computes the salt norm for a given sample solution. I was given a copy of the original .FOR file (SNORM2.FOR) and used gfortran to compile under linux - however I think there is some problem in the code when compiled under linux - it seems to accept user input from the terminal up to a point then produces the below error. It was previously compiled under windows and wonder if there is a subtle change to the code I need to apply throughout to overcome any issues with user input.

The .FOR code, a database of constants needed by the software (neodat), the compiled program (.exe) and sample analysis file (QD1) are available at the below link. Follow the same steps below to generate the error and you will likely hit the same problem - struggling to understand the issue.

Help much appreciated.

Kind Regards,

pi@Razberry4:~/Programs/SNORM files/SNORM files $ sudo ./SNORM_1.exe                                                                                                               INPUT DATA SOURCE, OUTPUT OPTIONS, AND NEW INPUT DATA ENTRY
                  (After each line of entry -- enter <RETURN>)

 Status of water analyses for salt norm calculation (ENTER one code integer):
   "0"  Analyses currently in a file in the user's directory
   "1"  Analyses to be entered and written to a new data file

 ENTER NAME of proposed input data file (up to 10 character string):


               File name = QD1
 Creation of a new file with this name will overwrite
 and destroy the existing file!  ENTER one code integer:
     "0"  REENTER file name,
     "1"  CONTINUE and destroy existing file
     "2"  CALCULATE salt norm for the existing file
     "3"  TERMINATE this run

 Listing of samples in file??  "0" = no; "1" = yes


  1.     qd1

 Selection of samples in file for output:
     "0" All samples in file.
     "1" Only those to be listed by position in file.
     "2" Only those with solutes to be specified.
     "3" Both "1" and "2" above.

 Your output file = QD1.out

 ENTER ONE desired option identifier integer:
          [If entry >0, additional options can be subsequently selected]
   "1"  Print-out of SNORM solute and salt data bank
   "2"  Salts in units other than those of water analysis
   "3"  Salt equivalencies rather than mole quantities
   "4"  Dissolved nitrate recast as ammonium
   "5"  Dissolved ammonium recast as nitrate
   "6"  Dissolved nitrate replaced by bicarbonate
   "7"  Selected solutes reset to 0.0 concentration

At line 816 of file SNORM.FOR (unit = 5, file = 'fort.5')
Fortran runtime error: End of file

Welcome to the forum, Mike.

The program has some errors. Among those, there is one that a modern compiler will probably balk at. The following lines refer to or contain statement no. 504:

T:\LANG>grep -in 504 SNORM.FOR
1483:      do 504 i=1,5
1485:      if( go to 504
1487:  504 continue
1530:      write(nu(1),610,err=504) (lw1(i),i=1,5),

The DO 504 loop is short, spanning just five lines. The ERR= clause in the WRITE statement of line 1530 is illegal, since it attempts to transfer into the range of a DO loop from a location outside the loop.

Apparently, the program worked on some old computer. To get the program working correctly, we need to know which computer(s) that was, what compiler was used, etc., and some test case for which input data and expected output results are available and may be used as reference information, to be reproduced to the extent possible.

One plausible fix, if I read the intent of the program correctly, is to replace “504” by “506” in line 1530. You may try making this change, building and running the program to see if the output is reasonable. I suggest, in addition, that in the OPEN statements for output files you replace the STATUS=‘NEW’ clause with STATUS=‘REPLACE’, especially during program development.

P.S. More problems. The program opens unit 5 for output and then continues to read from the standard input unit (= 5 on most Fortran processors). There may be similar misuse of unit numbers in other places, since it appears to attempt to open a file for writing when that very file is already open for writing but with a different unit number.

What does that do loop do? Its existence doesn’t make sense.

Sorry, I removed lines in-between, that’s why it does not make sense. Here is the program section.

      do 504 i=1,5
         if(lw1(i).eq.nul6(1)) lw1(i) = nul6(2)
         if( go to 504
         if(lw2(i).eq.nul5(1)) lw2(i) = nul5(2)
  504 continue
      go to 506
  505 continue
      print 603
      if (DOS) print 1000
      go to 503
  506 continue

1 Like

Hi all,


Thank you so much for looking at this.

I’ve made those changes surrounding 504 and STATUS and recompiled without success. I think the main problem is as you say in the opening of files and transfer from terminal. I don’t suppose you could elaborate a little on your explanation on this - really appreciate it.


not sure the loops function myself to be honest, unpicking old open source code in a language I’m not familiar with, creek and paddle come to mind :slight_smile:

As a general question to all - Is there a good IDE out there that can help me trace through the logic in the programme better, viewing in a text editor is just too hard for a newbie.


Given the complexity of the program code, without having at least one reference test case with known results, I am afraid that tinkering with the program will most likely botch it further. As it is, the IF (DOS) … modifications are, in my estimate, probably responsible for introducing new errors that did not exist in the program in the form listed in the USGS report.

I did apply some code transformation tools to the code and was able to compile and run, but I have no idea if the output/behavior are correct.

Please throw some light on why the IF (DOS) … blocks of code were added, if you know.

All the caveats above are true; but to just make it run change

   if(i.eq.4) nu(i) = 5


if(i.eq.4) nu(i) = 55

because it does not treat LUN 5 as preassigned and opens and closes it; and then still assumes a


still reads from stdin; and
uncomment the line setting DOS = .false. and comment out the one setting it to true. That will let it run past where you are seeing a failure, but who knows what happens next. As mentioned, without some unit tests I have no idea if it is running correctly, etc. Odd, but I have not seen a “READ FORMAT” in ages. Not really sure why but I did not even know that was still standard. i guess I use IOSTAT and IOMESG and such so often I just always use the form READ(…) LIST.

PS; Not non-standard, but unit 5 being stdin has been “de-facto standard” for so long, it is surprising this program does not assume that. Do you know what programming environment (compiler, vintage, OS and level, …) this ever ran on? That would make it a lot easier to know or have an educated guess on what the original code meant to do sans more documentation and unit tests.