Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Homework Help: FORTRAN 77 read statement

  1. Feb 7, 2010 #1
    Using Fortran 77, I'm trying write a program which will read in the coordinates of the atoms in a molecule from this input file:

    C 0.8641 0.1885 -0.0550
    C 1.6904 1.2832 -0.0518
    C 3.0579 1.1437 -0.0197
    C 3.6120 -0.1296 0.0167
    C 2.7571 -1.2117 0.0051
    C 1.3999 -1.0697 -0.0319
    C 3.8348 2.4466 -0.0147
    O 3.1949 3.5035 -0.0635
    O 5.2264 2.5396 0.0432
    O 5.0391 -0.2600 0.0701
    C 5.8568 -1.4155 0.2362
    O 5.5015 -2.5866 0.4359
    C 7.3030 -1.1536 0.2016
    H -0.1283 0.3101 -0.0742
    H 1.2910 2.1997 -0.0732
    H 3.1452 -2.1331 0.0245
    H 0.8059 -1.8741 -0.0419
    H 5.4969 3.4603 0.0349
    H 7.8008 -2.0121 0.3247
    H 7.5452 -0.5201 0.9364
    H 7.5482 -0.7503 -0.6801

    The eventual aim is to calculate interatomic distances and the like, but for the moment I'm having trouble reading the numbers in correctly. My current program looks like this:

    PROGRAM Aspirin
    REAL ARRAY1(1:21,1:3)
    OPEN(UNIT=10, FILE='aspirin.xyz', STATUS='old')
    READ (10,5),((ARRAY1(I,J),J=1,3),I=1,21)
    PRINT *,'Array:'
    PRINT 6,((ARRAY1(I,J),J=1,3),I=1,21)
    5 FORMAT(1X,F8.4,F8.4,F8.4)
    6 FORMAT(F8.4,F8.4,F8.4)

    This prints out the array perfectly when I deleted the two lines above the array in the input file; unfortunately, I don't know how to start reading on the third line.

    I've tried reading in two blank lines(using //) in the read statement, but this doesn't work since they don't have the correct format. I've tried inserting // into the format state, but this skips two lines between each record. I've tried assigning two variables A and B as character strings for the first two lines, but I can't put them in the same READ statement then as the format's wrong, and if I put it in a separate statement the array tries to read from the beginning of the file anyway. I even tried reading in the array for i=3:23, but again the format was wrong for the first two lines and it wouldn't work.

    Basically, what it boils down to is that there must be a way to specify reading an array from a part of a file other than the beginning, but I don't know what it is. Any help would be gratefully appreciated!
  2. jcsd
  3. Feb 7, 2010 #2


    User Avatar
    Science Advisor
    Homework Helper

    Perhaps insert read(10,4) immediately before your read(10,5) statement; and insert 4 format(//).

    Or, if you do not want to use 4 format(//), perhaps only insert read(10,'(//)') immediately before your read(10,5) statement.
  4. Nov 18, 2010 #3
    Hello, it's an old question, but, for people googling for an answer (like me) it should still be useful to give one.
    Based on my own attempts and on a solution to a slightly more complicated question, at
    I believe that merely reading the two lines to character strings before the "real" read should actually work (no idea why it didn't for ronny45). So the code might now be:

    PROGRAM Aspirin
    REAL ARRAY1(1:21,1:3)
    character a
    OPEN(UNIT=10, FILE='aspirin.xyz', STATUS='old')

    READ (10,5),((ARRAY1(I,J),J=1,3),I=1,21)
    PRINT *,'Array:'
    PRINT 6,((ARRAY1(I,J),J=1,3),I=1,21)
    5 FORMAT(1X,F8.4,F8.4,F8.4)
    6 FORMAT(F8.4,F8.4,F8.4)

    For me it worked with pgfortran and ifort compilers, gfortran complained in the reading:
    At line 7 of file aspirin.for (unit = 10, file = 'aspirin.xyz')
    Fortran runtime error: Bad value during floating point read
    Where "7" seems to be random (was 6 in the first run and there is nothing special in neither of the lines)
    Hope that's useful.
    Last edited by a moderator: Apr 25, 2017
  5. Mar 28, 2012 #4
    This is interesting guys. On a slightly more complicated point, I'm trying to read an a file like the following:


    File Created:
    March 29, 2010 - 01:19 PM

    Specimen Id:
    earth sample moffat attic

    Specimen Name:
    earth sample moffat attic

    Specimen Description:

    Scan Type: 2Theta Scan
    Start Angle: 5 deg.
    Stop Angle: 70 deg.
    Num Points: 3251
    Step Size: 0.02 deg.
    Scan Rate: 1.000000
    Scan Mode: Continuous
    Wavelength: 1.540562
    \Kalpha1: 1.540562 \Kalpha2: 1.544390 \Kbeta: 1.392218

    Type: Fixed Slits
    Type: Fixed Slits

    Pos [deg] Rate [CPS] ESD [-]

    Range 1 ---> Iteration 1
    5.000 169.17 14.248
    5.020 159.17 13.820
    5.040 185.00 14.900
    5.060 154.17 13.601
    5.080 156.67 13.711
    5.100 166.67 14.142
    5.120 180.00 14.697


    69.920 19.17 4.796
    69.940 16.67 4.472
    69.960 13.33 4.000
    69.980 25.00 5.477
    70.000 27.50 5.745

    I'm interested in the 3250 by 3 array of numbers and not the header. The number of lines of the header will be the same every time, but the individual characters will not. (i.e., file names will be of variable length).

    Any suggestion on how to read in and ignore this type of header, so as to only collect the data?
  6. Mar 28, 2012 #5
    In the same line of what's already here, you can read what you want to discard in a loop:
    Code (Text):

          do i=1,27
          do i=1,10000
     10   continue
    where 27 appears to be the number of non-empty lines in the header.

    Alternatively you could also first filter the file with something like (or hopefully better than):
    grep "[0-9]*\.[0-9]* [0-9]*\.[0-9]* [0-9]*\.[0-9]*" earth-moffat-attic_100329131917.raw >earth-moffat-attic_100329131917.dat

    if you'd want you could also include that command line (at least in some compilers, e.g., gfortran) in the fortran code itself:

    Code (Text):
          call system('grep "[0-9]*\.[0-9]* [0-9]*\.[0-9]* [0-9]*\.[0-9]*"'
         +     //' test.raw > temporary.dat')
          open(10, file='temporary.dat', status='old')
          do i=1,10000
     10   continue
          call system('/bin/rm temporary.dat')
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook