读取和制作制表符分隔的文本数据

时间:2015-04-01 06:00:33

标签: format fortran

我有一个以制表符分隔格式的Excel输出:

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

我需要将这些数字转换为FORMAT(1X,F7.0,2X,1P4E11.3)可读的另一个代码。 这就是我提出的:

 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

我一直收到这个错误:

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

有没有其他方法可以将数据转换为该格式?

2 个答案:

答案 0 :(得分:1)

您需要一个字符串,而不是标题

character
character(80)  header

除此之外,你的程序适合我。确保循环中有正确的行数

Do i=1,200

200调整为实际的数据行数。

如果由于某种原因你甚至无法阅读一行,你也可以使用以下格式:

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

因为标签只是一个你可以轻易跳过的字符。

注意:

未格式化和格式化意味着Fortran中完全不同的东西。未格式化的是您可能知道的"二进制"。

为程序使用一些缩进和空白行使其可读。

没有理由明确使用status=unknown。只是不要把任何东西放在那里。在您的情况下,status=replace可能更合适。

FORMAT语句已经过时,在现代Fortran中我们使用格式字符串:

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

你的return绝对没有理由在结束之前。返回是从程序提前返回。有些人将stop放在end program之前,但这是多余的。

答案 1 :(得分:0)

要读取制表符分隔的数据,我将使用一种简单的算法,如下所示。注意:这是假设您的任何字段中都没有制表符。

        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)