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

Error in writing strings

johnnyontheweb
Beginner
1,445 Views

Hi all,

I get a "forrtl: severe (66): output statement overflows record, unit -5" in this code, which tries to write a matrix to a CSV file with ";" separator:
 

CHARACTER(255) kterm,scrK
REAL*8 kcond(6,6)
...

OPEN(UNIT=200,FILE="K.CSV",STATUS="REPLACE",ACTION='WRITE')
do i=1,size(kcond,1)
do j=1,size(kcond,2)
    write(kterm,*)kcond(i,j)
    write(scrK,*)trim(adjustl(scrK))//';'//trim(adjustl(kterm)) ! error in this line
enddo
write(200,*)scrK
enddo
CLOSE(200)

any clue? It seems that the string scrK cannot hold the concat strings because they are too long. why trim(adjustl( don't do the magic? initially, scrK is empty. thanks in advance

0 Kudos
12 Replies
mecej4
Honored Contributor III
1,445 Views

You are writing 6 X 6 = 36 elements to a string with length 255. That allows a maximum of six characters per element, considering the space used by the semicolons. A list-directed write of a REAL*8 item will need more space.

You probably need to blank the string between matrix rows. That is, set SCRK = '' between lines 6 and 7 or between lines 11 and 12.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,445 Views

Have you considered opening the output with ACCESS='STREAM'?

Jim Dempsey

0 Kudos
johnnyontheweb
Beginner
1,445 Views

Thanks for the replies: I set scrK="" in line 7 and I increased the space in it (character(355) now), but the problem still persist, because I get a lot of spaces between a row and another... I still tried the ACCESS='STREAM', but the solution here is the same of performing a formatted output. The point is: I know I can use alternative code for that, but why the trim(adjustl( command doesn't work for blank lines? Is it a bug or am I missing something?

0 Kudos
mecej4
Honored Contributor III
1,445 Views

Jim's hint leads to the suggestion that, instead of assembling a line of output in the inner loop and then outputting a record for each matrix row, you can output each element as soon as it is available. With ACCESS='stream', you would need to output line feeds yourself, at the appropriate places.

0 Kudos
JVanB
Valued Contributor II
1,445 Views

Your last mistake is writing scrK to unit 200 rather than TRIM(scrK).

0 Kudos
mecej4
Honored Contributor III
1,445 Views

How about this, which summarizes what has been said:

program wrcsv
implicit none
CHARACTER(255) kterm,scrK
REAL*8 kcond(6,6)
integer i,j
do i=1,6
   do j=1,6
      kcond(i,j)=100.0*i+j
   end do
end do
OPEN(UNIT=200,FILE='K.CSV',STATUS='REPLACE',ACTION='WRITE',RECL=132)
do i=1,size(kcond,1)
   scrk=''
   do j=1,size(kcond,2)
      write(kterm,*)kcond(i,j)
      write(scrK,*)trim(adjustl(scrK))//trim(adjustl(kterm))//';'
   enddo
   write(200,*)trim(scrK)
enddo
CLOSE(200)
end

If you don't want a semicolon at the end of each line, you will need to modify the program suitably.

0 Kudos
johnnyontheweb
Beginner
1,445 Views

thanks, perfect, I was trying to reply before this last code but the forum site hangs on loading when trying to reply.

To

Your last mistake is writing scrK to unit 200 rather than TRIM(scrK)
: not exaclty, there will be trailing spaces in my original code. Better to use: trim(adjustl(scrK)) or the code by mecej4.

thanks all

0 Kudos
IanH
Honored Contributor III
1,445 Views

There might be a terminology mix-up in some of the above.  There wouldn't be much difference between formatted stream and formatted sequential for this case with ifort.  An advancing write statement under formatted stream access still adds a newline (as a record separator) after it has transferred the formatted representation of the output list to the file. 

Rather than the access mode, what could be considered is to change to non-advancing output (ADVANCE='NO').

Using "*" as a format specifier for production output makes me reach for my red pen (particularly when writing character strings that you then always shift left to eliminate the leading space).  I've ruined quite a few monitors as a consequence.  Consider the G0 format specification and its relatives for real data, A for character data.

0 Kudos
johnnyontheweb
Beginner
1,445 Views

Yes, good advice, in my final version I used always write(200,'(A)').

0 Kudos
Steven_L_Intel1
Employee
1,445 Views

You can use G0 for character data. Try it!

0 Kudos
andrew_4619
Honored Contributor III
1,445 Views

Steve Lionel (Intel) wrote:

You can use G0 for character data. Try it!

Interesting, I presume that is standard rather then extension?

Update >>>>

ISO/IEC JTC1/SC22/WG5 N1729 The new features of Fortran 2008 

7.2 g0 edit descriptor The g0 edit descriptor specifies that the processor should automatically choose a suitable field width. For real and complex data, it follows the rules of esw.dee format with the values of w, d, and e chosen by the processor. For integers, it behaves as i0. For logicals, it behaves as l1. For characters, it behaves as a.

0 Kudos
Steven_L_Intel1
Employee
1,445 Views

Yep, standard. Now, due to an oversight in F2008, G0.d is NOT allowed for character, but that is being fixed for F2015.

0 Kudos
Reply