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

How to read multiple data without changing line?

Zhanghong_T_
Novice
2,503 Views

Dear all,

I have a file without fixed number of data in every line. The example data are as follows:

0 0 0 30 45 0.2 0.001 5 0.005 0 0 1
0 0 1 0 0 0.2 0.001 1

For every line, if the eighth number is greater than 1, there are 4 data to be read, else if eighth number is equal to 1, there is no any data after that number.

How to design read format to read this kind of data?

Thanks,

Zhanghong Tang

 

0 Kudos
1 Solution
Steven_L_Intel1
Employee
2,503 Views

Arrgh. No, we don't support this extension. I thought we did. 

I see two ways to go here. First is to use an explicit format with field widths, assuming that the data has fixed positions in the record. The second is to read the whole record into a character string, use an internal read to get the eighth value, and then reread the string into values as needed.

View solution in original post

0 Kudos
10 Replies
Steven_L_Intel1
Employee
2,503 Views

I would do a READ with ADVANCE='NO' of the first eight values. Then if the eighth value is greater than 1, do another READ without ADVANCE='NO' of the remaining values, otherwise do a READ, without ADVANCE='NO', with an empty variable list.

0 Kudos
Zhanghong_T_
Novice
2,503 Views

Dear Steve,

Thank you very much for your kindly reply. I have the following code,

      do i=1,ncrackgroup
        read(1,'(e)',ADVANCE='NO')crackgroup(i)%x,crackgroup(i)%y,crackgroup(i)%z
        read(1,'(e)',ADVANCE='NO')crackgroup(i)%theta,crackgroup(i)%fai
        read(1,'(e)',ADVANCE='NO')crackgroup(i)%radius,crackgroup(i)%thickness
        read(1,'(i)',ADVANCE='NO')crackgroup(i)%ncrack
        if(crackgroup(i)%ncrack>1)then
          read(1,*)crackgroup(i)%space,crackgroup(i)%xn,crackgroup(i)%yn,crackgroup(i)%zn
        else
          read(1,*)
        endif
      enddo

but it crashed as the following message:

forrtl: severe (64): input conversion errors, unit 1, file ...

Is there anything missed in my code?

Thanks

0 Kudos
Anthony_Richards
New Contributor I
2,503 Views

 I presume that the following

  else
  read(1,*)
  endif

 is meant to read a blank record that separates the data records?

 

0 Kudos
Zhanghong_T_
Novice
2,503 Views

yes. I designed to let it jump to next line.

But the crash happened when reading the first line data.

Thanks

0 Kudos
Steven_L_Intel1
Employee
2,503 Views

Rather than use '(e)' and '(i)' for the formats in the initial reads, use *. The problem is that just e and i apply default field widths and you're not reading the values correctly. (I'll also comment that formats e and i without widths are an extension.) List directed (format *) should do what you want. Otherwise you have the right idea.

0 Kudos
mecej4
Honored Contributor III
2,503 Views

Steve, I thought list-directed I/O could not be used with the ADVANCE= clause, and an explicit format spec. would be needed (F2008, 9.6.2.1, C922 (R913)).

Are you allowing list-directed input in combination with ADVANCE='NO' as an extension and, if so, starting from which version of IFort?

0 Kudos
Steven_L_Intel1
Employee
2,503 Views

Yes, you're right that this is an extension - I had forgotten that. We have supported this, I think, as long as we've supported non-advancing I/O. But it is exactly what is wanted here (unless Zhanghong knows the exact layout of the record.)

0 Kudos
Zhanghong_T_
Novice
2,503 Views

Steve Lionel (Intel) wrote:

Rather than use '(e)' and '(i)' for the formats in the initial reads, use *. The problem is that just e and i apply default field widths and you're not reading the values correctly. (I'll also comment that formats e and i without widths are an extension.) List directed (format *) should do what you want. Otherwise you have the right idea.

Dear Steve,

The use of * , i.e.

        read(1,*,ADVANCE='NO')crackgroup(i)%x,crackgroup(i)%y,crackgroup(i)%z
        read(1,*,ADVANCE='NO')crackgroup(i)%theta,crackgroup(i)%fai
        read(1,*,ADVANCE='NO')crackgroup(i)%radius,crackgroup(i)%thickness
        read(1,*,ADVANCE='NO')crackgroup(i)%ncrack
        if(crackgroup(i)%ncrack>1)then
          read(1,*)crackgroup(i)%space,crackgroup(i)%xn,crackgroup(i)%yn,crackgroup(i)%zn
        else
          read(1,*)
        endif

will lead to the following compiling errors:

error #6568: This use of the ADVANCE, SIZE, or EOR specifier is invalid.

 

Is there anything missed?

Thanks

0 Kudos
Steven_L_Intel1
Employee
2,504 Views

Arrgh. No, we don't support this extension. I thought we did. 

I see two ways to go here. First is to use an explicit format with field widths, assuming that the data has fixed positions in the record. The second is to read the whole record into a character string, use an internal read to get the eighth value, and then reread the string into values as needed.

0 Kudos
Zhanghong_T_
Novice
2,503 Views

Dear Steve,

Thank you very much for your kindly reply. I got it.

Thanks

0 Kudos
Reply