Read scientific formatted numbers from txt

后端 未结 2 551
面向向阳花
面向向阳花 2021-01-24 18:49

I would like to read and store scientific formatted numbers from a txt file, which is formatted and the numbers are separated by tabulator.

This is what I have so far:

相关标签:
2条回答
  • 2021-01-24 19:11

    Though there are no direct command to count the number of items in a line, we can count the number of periods or (E|e|D|d) by using the scan command. For example,

    program main
        implicit none
        character(100) str
        integer n  
        read( *, "(a)" ) str
    
        call countreal( str, n )
        print *, "number of items = ", n
    contains
    
    subroutine countreal( str, num )
        implicit none
        character(*), intent(in)  :: str
        integer,      intent(out) :: num
        integer pos, offset
    
        num = 0
        pos = 0
        do
            offset = scan( str( pos + 1 : ), "." )        !! (1) search for periods
            !! offset = scan( str( pos + 1 : ), "EeDd" )  !! (2) search for (E|e|D|d)
    
            if ( offset > 0 ) then
                pos = pos + offset
                num = num + 1
                print *, "pos=", pos, "num=", num   !! just for check
            else
                return
            endif
        enddo
    endsubroutine
    end
    

    Please note that pattern (1) works only when all items have periods, while pattern (2) works only when all items have exponents:

    # When compiled with (1)
    
    $ echo "2.9900  2.8000E-35  2.6300D-35  2.46  2.31" | ./a.out
     pos=           2 num=           1
     pos=          10 num=           2
     pos=          22 num=           3
     pos=          34 num=           4
     pos=          40 num=           5
     number of items =            5
    
    # When compiled with (2)
    
    $ echo "2.9900E-35  2.8000D-35  2.6300e-35  2.4600d-35" | ./a.out
     pos=           7 num=           1
     pos=          19 num=           2
     pos=          31 num=           3
     pos=          43 num=           4
     number of items =            4
    

    For more general purposes, it may be more convenient to write a custom "split()" function that separate items with white spaces (or use an external library that supports a split function).

    0 讨论(0)
  • 2021-01-24 19:34

    Yes, your format is not good for the data you show. Better one should be like that read(99,'(6(E11.4,X))') myData(i,:).

    However, I am not sure if you really need to use format at your reading at all.

    Following example pretty close to what you are trying to do, and it is working bot with and without format.

    program readdata
      implicit none
      real, allocatable :: myData(:,:)
      real              :: myLine
      integer           :: i, j, myRow, myColumn
      character(len=30) :: myFileName
      character(len=30) :: myFormat
    
      myFileName='data.dat'
    
      open(99, file=myFileName)
      write(*,*)'open data file'
      read(99, *) myRow
      read(99, *) myColumn
    
      allocate(myData(myRow,myColumn))
    
      do i=1,myRow
        read(99,*) myData(i,:)
        !read(99,'(6(E11.4,X))') myData(i,:)
        print*, myData(i,:)
      enddo
    
      close(99)
    
    end program readdata
    

    To test, I assumed that you have rows and columns always in the file, as you give, so my test data was following.

    2
    6
    2.9900E-35  2.8000E-35  2.6300E-35  2.4600E-35  2.3100E-35  2.1600E-35
    2.9900E-35  2.8000E-35  2.6300E-35  2.4600E-35  2.3100E-35  2.1600E-35
    

    If you are really interested to read your files with a format and if the number of columns are not constant you may need a format depending on a variable, please see related discussions here.

    0 讨论(0)
提交回复
热议问题