Read and write tab-delimited text data

浪尽此生 提交于 2020-01-06 18:14:18

问题


I have an excel output in the tab-delimited format:

temperature H2O  CO2     N2      NH3     
10  2.71539E+12 44374931376 7410673406  2570.560804
20  2.34216E+12 38494172272 6429230649  3148.699673
30  2.04242E+12 33759520581 5639029060  3856.866413
40  1.75491E+12 29172949817 4882467457  4724.305292
.
.
.

I need to convert these numbers to FORMAT(1X,F7.0,2X,1P4E11.3) readable for another code. This is what I've come up with:

 program fixformat

  real temp, neuts(4)
  integer i,j
  character header

  open(11,file='./unformatted.txt',status='old')
  open(12,file='./formatted.txt',status='unknown')

  read(11,*) header
  write(12,*) header

  do i = 1, 200
    read(11,*) temp, (neuts(j),j=1,4)
    write(12,23) temp, (neuts(j),j=1,4)
  end do

23    FORMAT(1X,F7.0,2X,1P4E11.3)
  close(11)
  close(12)

  return
 end

I keep getting this error:

Fortran runtime error: Bad real number in item 1 of list input

Is there any other way to convert the data to that format?


回答1:


You need a character string, not a single character for the header

character(80)  header

other than that you program works for me. Make sure you have the right number of lines in your loop

Do i=1,200

Adjust 200 to the real number of your data lines.

If for some reason you still cannot read even a single line, you can also use the format:

read(11,'(f2.0,4(1x,f11.0))') temp, (neuts(j),j=1,4)

because the tab is just a character you can easily skip.

Notes:

Unformatted and formatted means something completely different in Fortran. Unformatted is what you may know as "binary".

Use some indentation and blank lines for your programs to make them readable.

There is no reason to explicitly use status=unknown. Just don't put anything there. In your case status=replace may be more appropriate.

The FORMAT statement is quite obsolete, in modern Fortran we use format strings:

write(12,'(1X,F7.0,2X,1P4E11.3)') temp, (neuts(j),j=1,4)

There is absolutely no reason for your return before the end. Returns is for early return from a procedure. Some put stop before the end program, but it is superfluous.




回答2:


To read tab delimited data, I'd use a simple algorithm like the one below. NOTE: This is assuming that there is no tab character in any of your fields.

        integer :: error_code, delim_index, line_index
        character*500 :: data_line, field_data_string
        double precision :: dp_value

        Open(Unit=1001,File="C:\\MY\\PATH\\Data.txt")

DO
   Read(UNIT=1001,End=106, FMT='(A)' ) data_line
   line_length = LEN(TRIM(data_line))
   delim_index = SCAN(data_line, achar(9) )
   line_index = 0
   DO WHILE ( delim_index .NE. 0 )
       line_index = line_index + delim_index
       IF (delim_index .EQ. 1 ) THEN ! found a NULL (no value), so skip
           GOTO 101
       END IF
       field_data_string = data_line( (line_index-delim_index+1) : line_index   )
       READ( field_data_string, FMT=*, ERR=100) dp_value
       PRINT *, "Is a double precision ", dp_value
       GOTO 101
       100 Continue
       PRINT *, "Not a double precision"
       101 Continue
        IF ( (line_index+1) .GT. line_length ) THEN
           GOTO 104 ! found end of line prematurely
        END IF
       delim_index = SCAN( data_line( line_index + 1 : ), achar(9) )
   END DO
   field_data_string = data_line( line_index + 1 :  )
   READ( field_data_string, FMT=*, ERR=102) dp_value
   PRINT *, "Is a double precision ", dp_value
   GOTO 103
   102 Continue
   PRINT *, "Not a double precision"
   103 Continue
    PRINT *, "Is a double precision ", dp_value
   104 Continue
END DO

            104 Continue
                PRINT *, "Error opening file"
            105 Continue
                Close(1001)


来源:https://stackoverflow.com/questions/29383838/read-and-write-tab-delimited-text-data

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