1

BACKSPACE moves the file position back by one record so that the record can be re-read or over-written. Is there a way to move the file position back by just one single character, so as to be able to over-write it? I've tried with TL1 added on the format sequence, this is the code:

c   DATA FROM 1 MINUTE TO nm MINUTS: reading a 1-min input file,
c   then writing mean values thru nm minuts, in an output file.
C   THE FAILURE IS AT THE END, UNDER write(9..)
    implicit real*4 (a-h,o-z)
    character*18 m
    character*15 t
    character*10 n
    character*12 nt,nd
    character*2 s
    integer id,io,nm
    dimension m(86)
        dimension a(31),id(31)

       open(8,file='CR1000_Meteo_Ximeniano01min.dat',status='old')

3       write(6,'(A)',advance='no')"Data from 1 min to how many minutes? 
      1 (max. 60) "
    read(5,*) nm
    if(60./nm.ne.aint(60./nm))goto 3
    write(s,'(I2.2)') nm
        open(9,file='CR1000_Meteo_Ximeniano'//s//'min.dat',
     1  status='replace')

    do l = 8,31
    a(l) = 0.
    id(l)= 0
    enddo     

    do i = 1,44640  
    read(8,'(1x,A4,1x,A2,1x,A2,1x,A2,1x,A2,1x,A2,2x)',
     1  advance='no')(m(l),l=1,6)
    read(8,*)(m(l),l=7,31)

    do l = 8,31
    if (m(l).ne.'NAN') then

c   n° OF DECIMAL DIGITS, id(l):
        id(l) = max(id(l),len(trim(m(l)))-index((m(l)),'.')
     1  -0**index((m(l)),'.')*len(trim(m(l))))
c       n° OF TOTAL DIGITS, DECIMAL POINT INCLUDED, nt:
    write(nt,*)len(trim(adjustl(m(l)))) 

    read(m(l),*)aa
    a(l) = a(l) + aa
    endif
    enddo
        if(float((i)/nm).eq.float(i)/nm)then

c   WRITING IN THE OUTPUT FILE:
        write(9,'(14A)',advance='no')'"',trim(m(1)),'-',trim(m(2
     1  )),'-',trim(m(3)),' ',trim(m(4)),':',trim(m(5)),':'
     1  ,trim(m(6)),'",',trim(m(7))

    do l = 8,31
    write(nd,*) id(l)
    if (m(l)=='NAN') then
    write(9,'(A)',advance = 'no')',"NAN"'
    else

ccc s=('.' // trim(adjustl(nd)))(1:2*(1-0**index(m(l),'.')))
ccc n="(A," // achar(70+0**index(m(l),'.')*3)  
ccc     1  // trim(adjustl(nt)) // s // ")" 

    r = a(l)/nm
c   ROUNDING OFF r IF IT HAS MANY ZEROS AFTER DECIMAL POINT:
    if(abs(r-anint(r)).le.(1.+abs(r))*1.e-5) r = anint(r)

c   CHECKING OUT TRAILING ZEROS:
    write(m(7),*) r
    m(7)=adjustl(m(7))
      j = len(trim(m(7)))
             do while (m(7)(j:j)=='0')
         j = j-1
         enddo
c     m(7) is now m(7) WITHOUT TRAILING ZEROS:
      m(7) = m(7)(1:j)

c   n° OF DECIMAL DIGITS, nd:
    io = min(id(l),len(trim(m(7)))-index(m(7),'.'))
        write(nd,*) io
c       n° OF TOTAL DIGITS, DECIMAL POINT INCLUDED, nt:
    write(nt,*)index(m(7),'.') + io  

c   n IS THE FORMAT FOR THE WRITE(9,...) STATEMENT 
    n="(A,F" // trim(adjustl(nt)) // trim('.') 
     1      // trim(adjustl(nd)) // ")" 
    write(t,n)r

    write(9,n,advance= 'no')',',r
c   IF THE REAL NUMBER r HAS NO DECIMAL DIGITS, ELIMINATE '.':
C   >>BUT THIS FAILS TO OVERWRITE THE DECIMAL POINT !! <<
        if(nd.eq.0) write(9,'(TL1)',advance='no')

    endif
    enddo
          do l = 8,31
          a(l) = 0.
          id(l)= 0
          enddo
    write(9,*)
    endif

    enddo

The output file is of the kind (note the 0. and the 7999.)

"2021-10-01 00:30:00",64875,13.8448343,19.9088326,0.,2.43821669,-4.82129955,7999.,7999.,"NAN","NAN","NAN",19.5433311,52.2050018,"NAN",7999.,"NAN",0.891549945,"NAN","NAN","NAN","NAN","NAN",2.43821669,114.979996,24.0228329  

I know I can handle real variables as strings and then writing them without decimal point, but I would like to avoid doing so.

I use gfortran from gcc-11.2.0 (mingw32) in windows 10.

EDIT by Ian Bush in an attempt to include a simpler and more readable example:

ijb@ijb-Latitude-5410:~/work/stack$ cat wr.f90
Program wr

  Write( *, * ) 'Advancing I/O'
  Write( *, '( f5.0, tl1, f5.2 )' ) 5.0, 7.21
  Write( *, * )
  Write( *, * ) 'Non-Advancing I/O'
  Write( *, '( f5.0, tl1, f5.2 )', Advance = 'No' ) 5.0, 7.21
  Write( *, * )
  Write( *, * )
  Write( *, * ) 'Non-Advancing I/O in stages'
  Write( *, '( f5.0 )', Advance = 'No' ) 5.0
  Write( *, '( tl1  )', Advance = 'No' ) 
  Write( *, '( f5.2 )', Advance = 'No' ) 7.21
  Write( *, * )

End Program wr
ijb@ijb-Latitude-5410:~/work/stack$ gfortran --version
GNU Fortran (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

ijb@ijb-Latitude-5410:~/work/stack$ gfortran -Wall -Wextra -fcheck=all -std=f2008 wr.f90
ijb@ijb-Latitude-5410:~/work/stack$ ./a.out
 Advancing I/O
   5 7.21

 Non-Advancing I/O
   5 7.21

 Non-Advancing I/O in stages
   5. 7.21
ijb@ijb-Latitude-5410:~/work/stack$ 
Ian Bush
  • 6,996
  • 1
  • 21
  • 27
ifffam
  • 59
  • 6
  • 2
    This works as expected for me in both gfortran and ifort on Linux. Please tell us the compiler, compiler version and platform, and show us a complete code that displays the problem, and the exact output on the screen/in the file - please cut and paste, not a screen shot. – Ian Bush Dec 13 '21 at 20:43
  • 3
    @veryreverie, I've rolled back your edit for the reason I stated [in my review](https://stackoverflow.com/review/suggested-edits/30578629). While it's a good guess of a [mre], in creating an example we create a danger than the asker gets an answer to a completely different problem than the one experienced (note Ian Bush's comment about reproducibility). – francescalus Dec 13 '21 at 21:26
  • 1
    I've included a much simpler and more readable example that doesn't require external files - iffam, could you confirm that this shows the same issue that you are concerned about? If so we can use it as an example, I'm afraid the code you have provided can't be run by a third party due to the dependence on external files, making it of limited use as an example. It it doesn't show the same behaviour I will delete it. – Ian Bush Dec 13 '21 at 22:45
  • 1
    Answers to the linked question suggest "hacks" to ensure you can delete the "." in your approach, but the question itself also gives details of _why_ your attempt isn't deleting it already. In short: `TLn` at the start of an output statement has no effect at all. – francescalus Dec 14 '21 at 00:00
  • Right ! TLn at the start of an output statement has no effect at all, but, unfortunately, neither has it at the end: it always should come in between.@Ian Bush, your example confirms it: doing it in stages has no effect since there, we have an statement in which tl1 appears at the end (or at the beginning, since it comes alone). So I must add the tl1 in my format string, somehow in the middle... hard to do so in the same write statement, so I fear I will have to add an additional if statement (if no. of decimals == 0) to modify the last part of the format string: adding tl1 and a spurious "" – ifffam Dec 14 '21 at 03:03

0 Answers0