Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29569 Обсуждение

How to read multiple data without changing line?

Zhanghong_T_
Новичок
4 382Просмотр.

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 баллов
1 Решение
Steven_L_Intel1
Сотрудник
4 382Просмотр.

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.

Просмотреть решение в исходном сообщении

10 Ответы
Steven_L_Intel1
Сотрудник
4 382Просмотр.

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.

Zhanghong_T_
Новичок
4 382Просмотр.

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

Anthony_Richards
Новый участник I
4 382Просмотр.

 I presume that the following

  else
  read(1,*)
  endif

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

 

Zhanghong_T_
Новичок
4 382Просмотр.

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

But the crash happened when reading the first line data.

Thanks

Steven_L_Intel1
Сотрудник
4 382Просмотр.

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.

mecej4
Почетный участник III
4 382Просмотр.

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?

Steven_L_Intel1
Сотрудник
4 382Просмотр.

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

Zhanghong_T_
Новичок
4 382Просмотр.

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

Steven_L_Intel1
Сотрудник
4 383Просмотр.

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.

Zhanghong_T_
Новичок
4 382Просмотр.

Dear Steve,

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

Thanks

Ответить