Read scientific formatted numbers from txt

无人久伴 提交于 2019-12-20 04:28:21

问题


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:

IMPLICIT NONE

REAL,ALLOCATABLE,DIMENSION(2)    :: data(:,:)       
INTEGER              :: row,column
INTEGER              :: j,i
CHARACTER(len=30)        :: filename
CHARACTER(len=30)        :: format

filename='data.txt'
open(86,file=filename,err=10)
write(*,*)'open data file'   
read(86, *) row
read(86, *) column

allocate(data(row,column))

format='(ES14.7)'   

do i=1,row
  read(86,format) data(i,:)
enddo

close(86)

This is how the txt file looks like:

200
35
2.9900E-35  2.8000E-35  2.6300E-35  2.4600E-35  2.3100E-35  2.1600E-35  ...

The problem is that it doesn't read and store the correct values from the txt to the data variable. Is it the format causing the problem?

I would also like to know how to count the number of columns in this case. (I can count the rows by using read(86,*) in a for loop.)


回答1:


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.




回答2:


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).



来源:https://stackoverflow.com/questions/40058712/read-scientific-formatted-numbers-from-txt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!