reading data from txt file in fortran

前端 未结 6 1307
渐次进展
渐次进展 2020-12-17 23:53

I am writing a FORTRAN program that reads data from a text file and writing it to the console. the data file looks something like this

1234567890123456 12345         


        
相关标签:
6条回答
  • 2020-12-17 23:56

    I had the hardest time ever trying to use read, but finally... If you want to read a matrix stored in a .txt file use this:

    program FILEREADER
    
       real, dimension(:,:), allocatable :: x
       integer :: n,m
    
       open (unit=99, file='array.txt', status='old', action='read')
       read(99, *), n
       read(99, *), m
       allocate(x(n,m))
    
       do I=1,n,1
          read(99,*) x(I,:)
          write(*,*) x(I,:)
       enddo
    
    end
    

    And the "array.txt" file must be like this for instance (And placed in the same folder of the main):

    4
    3
    0.0 1.0 2.0
    3.0 4.0 5.0
    6.0 7.0 8.0
    9.0 10.0 11.0
    

    Hope it works for everyone out there

    0 讨论(0)
  • 2020-12-18 00:00

    The reason is that you're specifying a width that is too small for the real numbers. Usually when the width doesn't fit, fortran will display asterisks, which happens in your case.

    You have 9 digits, but you'll need at least 10, since the comma takes up a column as well. So replacing 3F9.3 with 3F10.3 should do the trick.

    0 讨论(0)
  • 2020-12-18 00:06

    I used fixed format because the editing and inspecting of input files having fixed column structure is easier than that of zigzag data. My problem was how the Fortran run-time reader procedures interpret the presence and absence of decimal dots. I am not sure that my solution was the best but I read the data lines as character arrays, split them to fields having length 12 characters then I read the fields by read(*) statements.

    0 讨论(0)
  • 2020-12-18 00:06

    Slight modification to the @Andrés Argüello Guillén answer.

    Unlike most other solutions, my code does not force you to specify in advance the number of rows and columns.

    CHARACTER(128) :: buffer
    
    integer strlen, rows, cols
    real, dimension(:,:), allocatable :: x
    
    OPEN (1, file = 'matrix.txt', status='old', action='read')
    
    !Count the number of columns
    
    read(1,'(a)') buffer !read first line WITH SPACES INCLUDED
    REWIND(1) !Get back to the file beginning
    
    strlen = len(buffer) !Find the REAL length of a string read
    do while (buffer(strlen:strlen) == ' ') 
      strlen = strlen - 1 
    enddo
    
    cols=0 !Count the number of spaces in the first line
    do i=0,strlen
      if (buffer(i:i) == ' ') then
        cols=cols+1
      endif
    enddo
    
    cols = cols+1
    
    !Count the number of rows
    
    rows = 0 !Count the number of lines in a file
    DO
      READ(1,*,iostat=io)
      IF (io/=0) EXIT
      rows = rows + 1
    END DO
    
    REWIND(1)
    
    print*, 'Number of rows:', rows
    print*, 'Number of columns:', cols
    
    allocate(x(rows,cols))
    
    do I=1,rows,1
      read(1,*) x(I,:)
      write(*,*) x(I,:)
    enddo
    
    CLOSE (1)
    

    matrix.txt

    0.0 1.0 2.0
    3.0 4.0 5.0
    6.0 7.0 8.0
    
    0 讨论(0)
  • 2020-12-18 00:06

    It is usually better to read data in non fixed format. And to leave some leading spaces so that numbers can fit when writing them out.

    integer(8) :: i
    real(4) :: x, y, z
    open(unit=1, file='data.txt')
    read(1,*)i, x, y, z
    write(*,'(i16, 3f11.3)')i, x, y, z
    end
    
    0 讨论(0)
  • 2020-12-18 00:12

    List-directed IO (i.e., *) is easier, especially on input. Nevertheless, there are times to use full IO control so that is worth understanding. On input, the data items and descriptors must line up by column. For input, in Fw.d, the d doesn't matter if you have a decimal point in the data item. The fields must be wide enough on both input and output. There need to be enough descriptors, of types which match the variables and the data items. Compare to this example program:

    program test_read
    
       implicit none
       integer, parameter :: VLI_K = selected_int_kind (18)
       integer, parameter :: DR_K = selected_real_kind (14)
    
       integer (VLI_K) :: i
       real (DR_K) :: a, b, c, d
    
       open (unit=15, file="data.txt", status='old',    &
                 access='sequential', form='formatted', action='read' )
    
       read (15, 110)  i, a, b, c, d
       110 format (I16, 4(1X, F10.0) )
       write (*, 120) i, a, b, c, d
       120 format ( I18, 4 (2X, F12.3) )
    
       read (15, *) i, a, b, c, d
       write (*, 120) i, a, b, c, d
    
    end program test_read
    
    0 讨论(0)
提交回复
热议问题