Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Fortran nonadvanced file read

Heo__Jun-Yeong
1,173 Views

Hi, I'm trying to make code that read output files of the software which I'm planning to use.

Each line of the output file is like below

int1 int2 'rest of the line'

The 'rest of the line' is different according to int2

For example, if int2 equals to 4, the 'rest of the line' is consist of 7 integers.

Or if int2 equals to 15, the 'rest of the line' is consist of 4 integers....etc

So, I made the reading part of the code like below:

read(1,*,advance='No') int1, int2
select case(int2)
  case(4)
    read(1,*) int3, int4, int5, int6, int7, int8, int9
  case(15)
    read(1,*) int3, int4, int5, int6
 ...
end select

However, when I compile it, the error message came out: error #6568: This use of the ADVANCE, SIZE, or EOR specifier is invalid.

I found that the '*' format should not be used in nonadvanced read (maybe..), but I can't apply the format like 'I' to the output file because each integer has only 1 space like:

line1: 1 2 ...

line2: 1234 56...

I don't know what to do...

0 Kudos
4 Replies
mecej4
Honored Contributor III
1,173 Views

You get more control over processing a line with variable content if you read the whole line into a character variable of sufficient length. You can then use internal reads from that variable, using various formats until you find the pattern that you seek. You can even capture the event when one format fails by placing an ERR= clause in the internal read, and then retry reading the same text with a different format.

Try this:

program readints                                                                                                                      
implicit none                                                                                                                         
integer :: i1,i2,ij(20),kount(20),i                                                                                                   
character(80) :: txt                                                                                                                  
kount(4)=7                                                                                                                            
kount(15)=4                                                                                                                           
! set other values for kount, as desired                                                                                              
do                                                                                                                                    
   read(*,'(I2,I3,1x,A)',end=100)i1,i2,txt                                                                                                     
   read(txt,*)(ij(i),i=1,kount(i2))                                                                                                   
end do                                                                                                                                
100 continue                                                                                                                          
end program 

Data file for the program:

23  4 71 61 51 41 31 21 11                                                                                                             
17 15 14 13 12 11   

You will need to adjust the formats so that they match the contents of the data files that you intend to read. 

0 Kudos
Heo__Jun-Yeong
1,173 Views

Thanks mecej4

But I can't use I2 or I3 (or something like that)in reading part because each line has different length

Below is some part of the file I wish to use.

1 15 2 0 1 1
1278 2 2 0 1 585 933 641
10617 4 2 0 1 3440 3296 3124 3730

They are not written like:

    1 15 2 0 1    1
 1278  2 2 0 1  585  933  641
10617  4 2 0 1 3440 3296 3124 3730

Maybe I need to make code that reads entire line in single character variable and then extracts each values.

I don't know how to make it yet but thanks for the idea.

0 Kudos
mecej4
Honored Contributor III
1,173 Views

Read each line into a character variable, and locate the second blank field.

Split the line around that blank.

Read i1 and i2 from the first split part using list-directed input.

Use the value of i2 in an implied DO list to read the numbers from the second part, again using list-directed reads.

0 Kudos
JVanB
Valued Contributor II
1,173 Views

Fortran IO can handle this but you don't want to write a whole lot of code like this:

program P
   implicit none
   integer int1, int2, int3, int4, int5, int6, int7, int8, int9
   integer iunit
   integer i
   open(newunit=iunit,file='OhMyGirl.txt',status='old')
   do
      read(iunit,*,end=10) int1, int2, &
         (int3,int4,int5,int6,int7,int8,int9,i=1,merge(1,0,int2==4)), &
         (int3,int4,int5,int6,int7,int8,i=1,merge(1,0,int2==2)), &
         (int3,int4,int5,int6,i=1,merge(1,0,int2==15))
      select case(int2)
         case(4)
            write(*,'(*(g0))') 'int1 = ',int2,', int2 = ',int2,', int3 = ', &
               int3,', int4 = ',int4,', int5 = ',int5,', int6 = ', &
               int6,', int7 = ',int7,', int8 = ',int8,', int9 = ',int9
         case(2)
            write(*,'(*(g0))') 'int1 = ',int2,', int2 = ',int2,', int3 = ', &
               int3,', int4 = ',int4,', int5 = ',int5,', int6 = ', &
               int6,', int7 = ',int7,', int8 = ',int8
         case(15)
            write(*,'(*(g0))') 'int1 = ',int2,', int2 = ',int2,', int3 = ', &
               int3,', int4 = ',int4,', int5 = ',int5,', int6 = ', &
               int6
         case default
            write(*,'(*(g0))') 'int1 = ',int2,'int2 = ',int2
      end select
   end do
10 continue
end program P

Input file as in Quote#3. Output was;

int1 = 15, int2 = 15, int3 = 2, int4 = 0, int5 = 1, int6 = 1
int1 = 2, int2 = 2, int3 = 2, int4 = 0, int5 = 1, int6 = 585, int7 = 933, int8 =
 641
int1 = 4, int2 = 4, int3 = 2, int4 = 0, int5 = 1, int6 = 3440, int7 = 3296, int8
 = 3124, int9 = 3730

 

0 Kudos
Reply