In fortran how to read all strings line by line from a .dat file in fortran

There are a few things I notice straight away:

  1. The line read(*, *) command(i) reads the first element of standard input, not from the file. I think you want to read(9, *).
  2. Actually, you'll probably want to read(9, '(A)') because you want to read the whole line, not just until the first element separator (i.e. space or comma).
  3. In your subroutine, you open the file again, under the same unit. That is... dangerous if not wrong. Better to just read from the file, then use the rewind command to move the read position back to the beginning of the file.

    program atom_test
    
        implicit none
        integer :: ios
        integer, parameter :: read_unit = 99
        character(len=200), allocatable :: command(:)
        character(len=200) :: line
        integer :: n, i
    
        open(unit=read_unit, file='data.dat', iostat=ios)
        if ( ios /= 0 ) stop "Error opening file data.dat"
    
        n = 0
    
        do
            read(read_unit, '(A)', iostat=ios) line
            if (ios /= 0) exit
            n = n + 1
        end do
    
        print*, "File contains ", n, "commands"
    
        allocate(command(n))
    
        rewind(read_unit)
    
        do i = 1, n
            read(read_unit, '(A)') command(i)
        end do
    
        close(read_unit)
    
        do i = 1, n
            print*, command(i)
        end do
    
    end program atom_test
    
  4. If you already dedicate 3000 lines in the beginning, there's no real reason to read everything twice:

    program atom_test
    
        implicit none
        integer :: ios
        integer, parameter :: read_unit = 99
        character(len=200) :: command(3000)
        integer :: n, i
    
        open(unit=read_unit, file='data.dat', iostat=ios)
        if ( ios /= 0 ) stop "Error opening file data.dat"
    
        n = 0
    
        do
            read(read_unit, '(A)', iostat=ios) command(n+1)
            if (ios /= 0) exit
            n = n + 1
        end do
    
        print*, "File contains ", n, "commands"
    
        close(read_unit)
    
        do i = 1, n
            print*, command(i)
        end do
    
    end program atom_test
    
  5. In your subroutine to read the number of lines in the file, you try to read a REAL from a file where the first word is often not a number. This might lead to IOSTAT being non-zero, even if you haven't reached the end of the file. Always read a character variable.


This post provides an answer to OP comment:

I want to get the elements separately from the ATOM rows in my data file

Assuming input.txt looks like:

ATOM  1   S2  LJ2  1   17.000  15.030  11.630  1.00  0.00                       
ATOM  2   S2  LJ2  2   13.290  11.340  15.900  1.00  0.00                       
ATOM  3   S2  LJ2  3   17.030  23.070  14.750  1.00  0.00                       
ATOM  4   S2  LJ2  4   15.360  14.840  9.480   1.00  0.00                       
ATOM  5   S2  LJ2  5   15.780  4.560   9.580   1.00  0.00                       
ATOM  6   S2  LJ2  6   5.350   22.490  11.110  1.00  0.00                       
ATOM  7   S2  LJ2  7   19.940  3.910   10.840  1.00  0.00                       
ATOM  8   S2  LJ2  8   20.380  13.360  15.680  1.00  0.00                       
ATOM  9   S2  LJ2  9   18.340  4.200   7.720   1.00  0.00                       
ATOM  10  S2  LJ2  10  18.610  16.530  9.910   1.00  0.00 

You could

  1. read columns into strings
  2. read real numbers from strings
  3. output the results

      program fort                                                              
      integer n, i                                                              
      parameter (n=10)                                                          
      real r1(n), r2(n), r3(n), r4(n), r5(n), r6(n), r7(n)                      
      character(len=255) format, s1(n), s2(n), s3(n), s4(n), s5(n),             
     &                           s6(n), s7(n), s8(n), s9(n), s10(n)             
      i=1                                                                       
      open(unit=99, file='input.txt')                                           
2     read(99,3,end=1) s1(i), s2(i), s3(i), s4(i), s5(i),                       
     &                 s6(i), s7(i), s8(i), s9(i), s10(i)                       
      i=i+1                                                                     
      goto 2                                                                    
3     format(a6,2a4,a5,a4,3a8,a6,a4)                                            
4     format(a6,f4.1,2x,2a4,f4.1,5f8.3)                                         
1     close(99)                                                                 
      read(s2,*) r1                                                             
      read(s5,*) r2                                                             
      read(s6,*) r3                                                             
      read(s7,*) r4                                                             
      read(s8,*) r5                                                             
      read(s9,*) r6                                                             
      read(s10,*) r7                                                            
      do i=1,n                                                                  
         write(*,4) s1(i), r1(i), s3(i), s4(i), r2(i),                          
     &              r3(i), r4(i), r5(i), r6(i), r7(i)                           
      enddo                                                                     
      end

output:

ATOM   1.0  S2  LJ2  1.0  17.000  15.030  11.630   1.000   0.000
ATOM   2.0  S2  LJ2  2.0  13.290  11.340  15.900   1.000   0.000
ATOM   3.0  S2  LJ2  3.0  17.030  23.070  14.750   1.000   0.000
ATOM   4.0  S2  LJ2  4.0  15.360  14.840   9.480   1.000   0.000
ATOM   5.0  S2  LJ2  5.0  15.780   4.560   9.580   1.000   0.000
ATOM   6.0  S2  LJ2  6.0   5.350  22.490  11.110   1.000   0.000
ATOM   7.0  S2  LJ2  7.0  19.940   3.910  10.840   1.000   0.000
ATOM   8.0  S2  LJ2  8.0  20.380  13.360  15.680   1.000   0.000
ATOM   9.0  S2  LJ2  9.0  18.340   4.200   7.720   1.000   0.000
ATOM  10.0  S2  LJ2 10.0  18.610  16.530   9.910   1.000   0.000

A better approach consists on

  1. read columns into variables (strings, integers, or reals)
  2. output the results
      program fort                                                              
      integer n, i                                                              
      parameter (n=10)                                                          
      integer i1(n), i2(n)                                                      
      real r1(n), r2(n), r3(n), r4(n), r5(n)                                    
      character(len=255) format, s1(n), s2(n), s3(n), s4(n), s5(n),             
     &                           s6(n), s7(n), s8(n), s9(n), s10(n)             
      i=1                                                                       
      open(unit=99, file='input.txt')                                           
2     read(99,3,end=1) s1(i), i1(i), s3(i), s4(i), i2(i),                       
     &                 r1(i), r2(i), r3(i), r4(i), r5(i)                        
      i=i+1                                                                     
      goto 2                                                                    
3     format(a6,i4,a4,a5,i4,3f8.3,2f6.2)                                        
4     format(a6,i4,2x,2a4,i4,5f8.3)                                             
1     close(99)                                                                 
      do i=1,n                                                                  
         write(*,4) s1(i), i1(i), s3(i), s4(i), i2(i),                          
     &              r1(i), r2(i), r3(i), r4(i), r5(i)                           
      enddo                                                                     
      end