How to handle blank in formatted integer input - fortran

I have a file like this
1980 01 23
1982 04 30
1983 05 22
1984
1985 02 11
I tried to read data using format "(3I4)"
implicit none
integer, parameter :: FUnitIn = 10
character(len=255) :: FNameIn = "./test.txt"
integer :: FStatOpen, FStatRead
integer :: yyyy, mm, dd
open ( unit = FUnitIn, &
file = trim(FNameIn), &
access = "sequential", &
form = "formatted", &
status = "old", &
iostat = FStatOpen)
if (FStatOpen /= 0) then ! ERROR
stop
end if
do
read (FUnitIn, "(3I4)", iostat=FStatRead) yyyy, mm, dd
if (FStatRead /= 0) then
exit
else
write (6, "(3I4)") yyyy, mm, dd
end if
end do
I got three zeros for the blank line.
Are there any options to handle blank input?

You can read each line in a character variable, and check its adjusted-trimmed length if your sole goal is to skip the empty line, something like the following code (see variable record). Going beyond this simple implementation requires some extra information from you as to what behavior exactly you want to get.
implicit none
integer, parameter :: FUnitIn = 10
character(len=255) :: FNameIn = "./test.txt"
integer :: FStatOpen, FStatRead
integer :: yyyy, mm, dd
character(len=1023) :: record
open ( unit = FUnitIn, &
file = trim(FNameIn), &
access = "sequential", &
form = "formatted", &
status = "old", &
iostat = FStatOpen)
if (FStatOpen /= 0) then ! ERROR
stop
end if
do
read (FUnitIn, "(3I4)", iostat=FStatRead) record
if (FStatRead /= 0) then
exit
elseif ( len_trim(adjustl(record)) > 0 ) then
read (record, *) yyyy, mm, dd
write (6, "(3I4)") yyyy, mm, dd
end if
end do

Related

how to write the minimum hourly value in fortran?

This script reads 5 day forecasts from a weather model, and averages a few variables monthly hourly.
Now, I need to get the minimum temperature value.
Example, each day I have 5 days of forecast.
I need an output like this:
January
minimum value of 0h, 1h, 2h, 3h, 4h, etc. It doesn't matter what day it is in January, just the monthly hourly minimum value.
program medias
implicit none
INTEGER,PARAMETER :: NVARS=5
INTEGER :: IM, JM, YEAR2, MONTH2, DAY2, YEAR, MONTH, DAY, LASTYEAR, &
LASTMONTH, LASTDAY, H1, H2, H3, H7, H8, A, B, V, X, Y, TDEF=0
REAL :: LAT, LON, RESX=0.0466611, RESY=0.0448676
INTEGER, DIMENSION(12) :: CALENDAR
CHARACTER(LEN=3), DIMENSION(12) :: MONTHS = (/ 'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec' /)
CHARACTER(LEN=5), DIMENSION(NVARS) :: VARNAMES = (/ 'PRECI','T2MJU','TD2MJ','U10MJ','V10MJ' /)
REAL, DIMENSION(:,:), ALLOCATABLE :: SURVAR
REAL, DIMENSION(:,:,:,:), ALLOCATABLE :: HOURLY2D, HOURLY2DF, MONTHLY2D, MONTHLY2DF
CHARACTER :: DATE*8, DIROUT*200, DIRRUN*200, FILENAME*200, DYEAR*4, DMONTH*2, DDAY*2, DHOUR*2
! DADOS DE ENTRADA
DIRRUN = '/media/milena/Backup/'
!DIRRUN = '/home/oper/prevtempo/dataout/GrADS_BRAMS-6.5.2/'
DIROUT = '/media/milena/Backup/'
IM = 259
JM = 269
CALENDAR = (/ 31,28,31,30,31,30,31,31,30,31,30,31 /)
H8 = 24
ALLOCATE(SURVAR(IM,JM))
ALLOCATE(HOURLY2DF(IM,JM,H8,5))
ALLOCATE(MONTHLY2DF(IM,JM,12,5))
! Iniciando o armazenamento de dados
TDEF = 0
YEAR = 2022
MONTH = 10
LASTMONTH = 10
LASTYEAR = 2022
H7 = 0
YEAR2 = YEAR
MONTH2 = MONTH
2 H7 = H7+1
H2 = 0
DO WHILE (H2 .LE. 23)
YEAR = YEAR2
MONTH = MONTH2
PRINT*, MONTH
PRINT*, YEAR
H1 = ((LASTYEAR-YEAR)+1)*31*5
ALLOCATE(HOURLY2D(IM,JM,H1,5))
H1 = 0
WRITE (DHOUR,'(BZ,I2.2)') H2
TDEF = TDEF+1
DO WHILE (YEAR .LE. LASTYEAR)
IF (MOD(YEAR,4) .EQ. 0) CALENDAR(2) = 29
LASTDAY = CALENDAR(MONTH)
! IF (MONTH .EQ. LASTMONTH) LASTDAY = 12
DAY = 1
DO WHILE (DAY .LE. LASTDAY)
DAY2 = DAY
A = 8
WRITE (DATE,'(BZ,I4.4,3I2.2)') YEAR,MONTH,DAY
WRITE (DYEAR,'(BZ,I4.4)') YEAR
WRITE (DMONTH,'(BZ,I2.2)') MONTH
IF (H2 .EQ. 0) THEN
DAY2 = DAY2+1
IF ( DAY2 .GT. LASTDAY ) THEN
GO TO 22
END IF
END IF
WRITE (DDAY,'(BZ,I2.2)') DAY2
8 FILENAME = TRIM(DIRRUN)//DATE//'00/Go05km-A-'//DYEAR//'-'//DMONTH//'-'//DDAY//'-'//DHOUR//'0000-g1.gra'
OPEN(8,FILE=TRIM(FILENAME),ACCESS="direct",ACTION="read",STATUS="old",RECL=IM*JM*4)
H1 = H1+1
GO TO 21
9 FILENAME = TRIM(DIRRUN)//DATE//'00/Go05km-A-'//DYEAR//'-'//DMONTH//'-'//DDAY//'-'//DHOUR//'0000-g1.gra'
OPEN(9,FILE=TRIM(FILENAME),ACCESS="direct",ACTION="read",STATUS="old",RECL=IM*JM*4)
H1 = H1+1
GO TO 21
10 FILENAME = TRIM(DIRRUN)//DATE//'00/Go05km-A-'//DYEAR//'-'//DMONTH//'-'//DDAY//'-'//DHOUR//'0000-g1.gra'
OPEN(10,FILE=TRIM(FILENAME),ACCESS="direct",ACTION="read",STATUS="old",RECL=IM*JM*4)
H1 = H1+1
GO TO 21
11 FILENAME = TRIM(DIRRUN)//DATE//'00/Go05km-A-'//DYEAR//'-'//DMONTH//'-'//DDAY//'-'//DHOUR//'0000-g1.gra'
OPEN(11,FILE=TRIM(FILENAME),ACCESS="direct",ACTION="read",STATUS="old",RECL=IM*JM*4)
H1 = H1+1
GO TO 21
12 FILENAME = TRIM(DIRRUN)//DATE//'00/Go05km-A-'//DYEAR//'-'//DMONTH//'-'//DDAY//'-'//DHOUR//'0000-g1.gra'
OPEN(12,FILE=TRIM(FILENAME),ACCESS="direct",ACTION="read",STATUS="old",RECL=IM*JM*4)
H1 = H1+1
GO TO 21
13 GO TO 22
21 B = 0
DO V =1,175
READ (A,REC=V) SURVAR(:,:)
! Leitura Precipitacao
IF ( V .EQ. 162 ) THEN
B = B+1
HOURLY2D(:,:,H1,B) = SURVAR(:,:)
END IF
! Leitura Tp2m
IF ( V .EQ. 166 ) THEN
B = B+1
HOURLY2D(:,:,H1,B) = SURVAR(:,:)
END IF
! Leitura Td2m
IF ( V .EQ. 167 ) THEN
B = B+1
HOURLY2D(:,:,H1,B) = SURVAR(:,:)
END IF
! Leitura U10m
IF ( V .EQ. 168 ) THEN
B = B+1
HOURLY2D(:,:,H1,B) = SURVAR(:,:)
END IF
! Leitura V10m
IF ( V .EQ. 169 ) THEN
B = B+1
HOURLY2D(:,:,H1,B) = SURVAR(:,:)
END IF
END DO
CLOSE(A)
A = A+1
DAY2 = DAY2+1
WRITE (DDAY,'(BZ,I2.2)') DAY2
IF ( DAY2 .GT. LASTDAY ) THEN
GO TO 22
END IF
GO TO (9,10,11,12,13),A-8
22 DAY = DAY+1
END DO
YEAR = YEAR+1
IF (MONTH .GT. LASTMONTH) THEN
GO TO 23
END IF
END DO
23 DO B=1,5
DO Y=1,JM
DO X=1,IM
HOURLY2DF(X,Y,H2,B) = SUM(HOURLY2D(X,Y,1:H1,B))/H1
END DO
END DO
END DO
PRINT*,H2
PRINT*, HOURLY2DF(130,107,H2,1)
PRINT*, HOURLY2DF(130,107,H2,2)
PRINT*, HOURLY2DF(130,107,H2,3)
PRINT*, HOURLY2DF(130,107,H2,4)
PRINT*, HOURLY2DF(130,107,H2,5)
DEALLOCATE(HOURLY2D)
H2 = H2+1
END DO
40 FILENAME = TRIM(DIROUT)//'MEDIA_HORARIA_'//DMONTH//'.bin'
PRINT*, FILENAME
OPEN(40,FILE=TRIM(FILENAME),ACCESS="direct",ACTION="write",STATUS="new",RECL=IM*JM*4)
H3=1
H2=H2-1
DO H2=0,H2
DO B=1,5
WRITE(40,rec=H3) HOURLY2DF(:,:,H2,B)
H3=H3+1
END DO
END DO
CLOSE(40)
DO B=1,5
DO Y=1,JM
DO X=1,IM
MONTHLY2DF(X,Y,H7,B) = SUM(HOURLY2DF(X,Y,0:H2,B))/(H2+1)
END DO
END DO
END DO
PRINT*,'MEDIA MENSAL DO MES ',DMONTH
PRINT*, MONTHLY2DF(153,117,H7,1)
PRINT*, MONTHLY2DF(153,117,H7,2)
PRINT*, MONTHLY2DF(153,117,H7,3)
PRINT*, MONTHLY2DF(153,117,H7,4)
PRINT*, MONTHLY2DF(153,117,H7,5)
MONTH2 = MONTH2+1
IF (MONTH2 .GT. 12) THEN
MONTH2 = 1
YEAR2 = YEAR2+1
END IF
IF (MONTH2 .LE. LASTMONTH) THEN
IF (H7 .LE. 12) THEN
GO TO 2
END IF
END IF
50 FILENAME = TRIM(DIROUT)//'MEDIA_MENSAL_01.bin'
OPEN(50,FILE=TRIM(FILENAME),ACCESS="direct",ACTION="write",STATUS="new",RECL=IM*JM*4)
H3=1
DO H7=1,H7
DO B=1,5
WRITE(50,rec=H3) MONTHLY2DF(:,:,H7,B)
H3=H3+1
END DO
END DO
CLOSE(50)
END PROGRAM medias

How to avoid printing on screen all reading format error messages if just one reading format is not correct?

This is my simple( test ) code:
MODULE TEST_MODULE
USE, INTRINSIC :: ISO_C_BINDING
IMPLICIT NONE
INTEGER, PARAMETER :: IP = C_INT
INTEGER, PARAMETER :: LP = C_BOOL
INTEGER, PARAMETER :: CP = C_CHAR
INTEGER( IP ), PARAMETER :: UN = 15
INTEGER( IP ) :: DATA_00, DATA_01, DATA_02
CHARACTER(*), PARAMETER :: FMTR = 'BASE\DATA_STORAGE.TXT'
CONTAINS
FUNCTION DATA_READING( ) RESULT( ERROR_TMP )
LOGICAL( LP ) :: ERROR_TMP
ERROR_TMP = .FALSE.
OPEN( UNIT = UN, FILE = FMTR, ACTION = 'READ', STATUS = 'UNKNOWN', ERR = 100 )
READ( UN, * , ERR = 101 ) DATA_00
READ( UN, * , ERR = 102 ) DATA_01
READ( UN, * , ERR = 103 ) DATA_02
CLOSE( UNIT = UN, STATUS = 'KEEP')
RETURN
100 WRITE(*,*) "ERROR - NO SUCH A FILE OR FILE LOCATION !!!"
ERROR_TMP = .TRUE.
101 WRITE(*,*) "ERROR - FMT OF READING - DATA_TMP_00 - 101 !!!"
ERROR_TMP = .TRUE.
102 WRITE(*,*) "ERROR - FMT OF READING - DATA_TMP_01 - 102 !!!"
ERROR_TMP = .TRUE.
103 WRITE(*,*) "ERROR - FMT OF READING - DATA_TMP_02 - 103 !!!"
ERROR_TMP = .TRUE.
END FUNCTION DATA_READING
END MODULE TEST_MODULE
PROGRAM TEST_CODE
USE, NON_INTRINSIC :: TEST_MODULE
IMPLICIT NONE
LOGICAL( LP ) :: GLOBAL_ERR
GLOBAL_ERR = DATA_READING()
IF ( GLOBAL_ERR ) STOP ( "ERROR - DATA READING !!!" )
PRINT *, DATA_00
PRINT *, DATA_01
PRINT *, DATA_02
END PROGRAM TEST_CODE
The DATA_STORAGE.TXT file contains:
1407
1408
1409
When I run the program, it will load the data from the specified file in the correct way - there will not be a global error message because all the data in the file is an integer type.
For example, if the changed value of the first data in 1407.23,which is real type, after the startup, the program will print on the screen all the error labels, including the one about the existence of a global error.
My question is:
How to print on the screen only the error label that belongs to the data whose entry format is not correct?
The code was tested in two IDE:
Code::Blocks 1712 GFortan 6.3.0
Visual Studio 2010 with Intel Parallel XE 2011

Fortran code gives outputs with only certain files

I have 4 .mtx files that I am reading the values from. Two of them run perfectly when read from with no issues and produce the correct outputs into a .DAT file. However, the last 2 are extremely large files; it appears the code correctly reads from the files and runs, but I get no outputs and no errors when reading from these 2...not even the code timer prints the time. Any help is much appreciated! Here is the code:
program proj2matrixC40
implicit none
integer,parameter::dp=selected_real_kind(15,307)
! Set Global Variables
real(kind=dp), allocatable::Ax(:,:),A(:,:),Iglobal(:,:)
integer::At(1,3)
integer::nnz,w,n,k,ii,ff,kk
real(kind=dp)::t1,t2
call cpu_time(t1)
open(unit=78,file="e40r5000.mtx",status='old')
read(78,*) At
close(unit=78)
nnz = At(1,3)
n = At(1,1)
k = 40
kk = 35
allocate(Ax(nnz+1,3),A(nnz,3),Iglobal(k,k))
open(unit=61,file="e40r5000.mtx",status='old')
do w=1,nnz+1
read(61,*) Ax(w,:)
end do
open (unit = 53, file = "proj2matrixC40points.dat")
do ff=1,k
do ii=1,k
Iglobal(ii,ff) = (ii/ff)*(ff/ii)
end do
end do
A(1:nnz,:) = Ax(2:nnz+1,:)
call Arno(A)
call cpu_time(t2)
print '("Time elapsed = ",f10.8," seconds")', (t2 - t1)
contains
subroutine Arno(a)
real(kind=dp), intent(in)::a(:,:)
real(kind=dp),dimension(k,k)::H
real(kind=dp),dimension(k,k+1)::u,q,qconj
real(kind=dp),dimension(k,1)::x0
integer::j,f
call random_number(x0)
q(:,1) = x0(:,1)/norm2(x0(:,1))
do f=1,k
call spmat(a,q(:,f),u(:,f))
do j=1,f
qconj(j,:) = (q(:,j))
H(j,f) = dot_product(qconj(j,:),u(:,f))
u(:,f) = u(:,f) - H(j,f)*q(:,j)
end do
if (f.lt.k) then
H(f+1,f) = norm2(u(:,f))
if (H(f+1,f)==0) then
print *, "Matrix is reducible"
stop
end if
q(:,f+1) = u(:,f)/H(f+1,f)
end if
if (f==k) then
call qrit(H)
end if
end do
end subroutine
! QR Iteration with Shifts Subroutine
subroutine qrit(a)
real(kind=dp), intent(in)::a(:,:)
real(kind=dp)::sigmak
real(kind=dp),dimension(kk,k)::dia
real(kind=dp),dimension(k,k)::Qfinal,Rfinal,HH
real(kind=dp),dimension(k,k,kk)::H0,needQR
integer::v,z
HH = a
H0(:,:,1) = HH
do v=1,kk
sigmak = H0(k,k,v)
if (v-1==0) then
needQR(:,:,v) = HH - sigmak*Iglobal
else
needQR(:,:,v) = H0(:,:,v-1) - sigmak*Iglobal
end if
call givens2(needQR(:,:,v),Rfinal,Qfinal)
H0(:,:,v) = matmul(Rfinal,Qfinal) + sigmak*Iglobal
do z = 1,k
dia(v,z) = H0(z,z,v)
write(53,*) v," ", dia(v,z) ! Write values to .DAT file
end do
end do
end subroutine
! Sparse Matrix Vector Multiplication Subroutine
subroutine spmat(a,b,c)
real(kind=dp), intent(in)::a(:,:)
real(kind=dp), intent(in), dimension(k,1)::b
real(kind=dp), intent(out), dimension(k,1)::c
integer::m,rowi,columni
real(kind=dp), dimension(k,1)::x,y
x = b
y(:,1) = 0
do m = 1,nnz
rowi = a(m,1)
columni = a(m,2)
y(rowi,1) = y(rowi,1) + a(m,3)*x(columni,1)
end do
c(:,1) = y(:,1)
end subroutine
! QR Factorization Givens Rotations Subroutine
subroutine givens2(a,Rfinal,Qfinal)
real(kind=dp), intent(in)::a(:,:)
real(kind=dp), dimension(k,k,(k*k))::G,QQ
real(kind=dp), dimension(k,k), intent(out)::Rfinal,Qfinal
real(kind=dp), dimension(k,k)::I2,y,aa
real(kind=dp), dimension(1,k)::ek1,ek2
real(kind=dp)::c,s
integer::kt,m,nn,j,i,l,p
m = size(a,1)
nn = size(a,2)
aa = a
i = 1
do kt=1,nn-1
do j=m,kt+1,-1
if (aa(j,kt).eq.0) then
continue
else
ek1(1,:) = 0
ek2(1,:) = 0
do p=1,m
do l=1,m
I2(l,p) = (l/p)*(p/l)
end do
end do
c = aa(kt,kt)/sqrt(aa(kt,kt)**2 + aa(j,kt)**2)
s = aa(j,kt)/sqrt(aa(kt,kt)**2 + aa(j,kt)**2)
ek1(1,kt) = c
ek1(1,j) = s
ek2(1,kt) = -s
ek2(1,j) = c
I2(kt,:) = ek1(1,:)
I2(j,:) = ek2(1,:)
G(:,:,i) = I2
if (i.eq.1) then
QQ(:,:,i) = G(:,:,i)
else
QQ(:,:,i) = matmul(G(:,:,i),QQ(:,:,i-1))
end if
y = matmul(G(:,:,i),aa)
aa = y
if (kt.eq.nn-1) then
if (j.eq.kt+1) then
Qfinal = transpose(QQ(:,:,i))
Rfinal = aa
end if
end if
i = i + 1
end if
end do
end do
end subroutine
end program proj2matrixC40
A couple notes. The line which I put asterisks around (for this question) call mat_print('H',H) can't be deleted otherwise I get the wrong answers (this is strange...thoughts?). Also so your computer won't freeze opening the big files, their names are 'e40r5000.mtx' and 's3dkt3m2.mtx' (these are the two I have issues with). I am using gfortran version 8.1.0
Here is the link to the files
https://1drv.ms/f/s!AjG0dE43DVddaJfY62ABE8Yq3CI
When you need to add a call to a subroutine that shouldn't actually change anything in order to get things working, you probably have a memory corruption. This happens most often when you access arrays outside of their boundaries.
I have compiled it with some run time checks:
gfortran -o p2m -g -O0 -fbacktrace -fcheck=all -Wall proj2mat.f90
And it's already giving me some issues:
It's warning me about implicit type conversions. That shouldn't be too much of an issue if you trust your data.
In line 46 you have an array length mismatch (x0(:, 1) has length 40, q(:,1) is 41)
Similarly on line 108 (x=b) x is really large, but b is only 41 long.
I have stopped now, but I implore you to go through your code and clean it up. Use the compiler options above which will let you know when and where there is an array bound violation.

Trouble reading reals from unknown length character string in Fortran

This is a small portion of the data I am trying to read:
01/06/2009,Tom Sanders,,264,220,73,260
01/08/2009,Adam Apple,158,,260,,208
01/13/2009,Lori Freeman,230,288,218,282,234
01/15/2009,Diane Greenberg,170,,250,321,197
01/20/2009,Adam Apple,257,,263,256,190
01/21/2009,Diane Greenberg,201,,160,195,142
01/27/2009,Tom Sanders,267,,143,140,206
01/29/2009,Tina Workman,153,,124,155,140
02/03/2009,Tina Workman,233,,115,,163
02/03/2009,Adam Apple,266,130,310,,310
the numbers between each comma are from a different location
Where two commas would represent missing data and a trailing comma would mean the fifth data point is missing
My goal is to organize the data into a table after calculating the average of each site and person, hence my two dim arrays
I want my output to look something like the following:
(obviously neater formatting but a table nonetheless)
Average Observed TDS (mg/l)
Name Site 1 Site 2 Site 3 Site 4 Site 5
------------------------------------------------------
Tom Sanders 251.0 172.5 251.7 160.0 229.0
Adam Apple 227.0 130.0 277.7 256.0 236.0
Lori Freeman 194.0 288.0 216.7 279.0 202.7
Diane Greenberg 185.5 190.0 205.0 258.0 169.5
Tina Workman 193.0 140.0 119.5 155.0 163.0
This is my program so far:
program name_finder
implicit none
integer, parameter :: wp = selected_real_kind(15)
real(wp) :: m, tds
real(wp), dimension(20,5) :: avg_site, site_sum
integer, dimension(20) :: nobs
integer, dimension(5) :: x
integer :: ierror, i, nemp, cp, non, ni, n
character(len=40), dimension(20) :: names
character(len=200) :: line, aname
character(len=20) :: output, filename
character(len=3), parameter :: a = "(A)"
do
write(*,*) "Enter file to open."
read(*,*) filename
open(unit=10,file = filename, status = "old", iostat = ierror)
if (ierror==0) exit
end do
write(*,*) "File, ",trim(filename)," has been opened."
non = 0
outer: do
read(10,a, iostat = ierror) line
if (ierror/=0) exit
cp = index(line(12:),",") + 11
aname = line(12:cp-1)
n=0
middle: do
read(line,'(Tcp,f4.2)') tds
write(*,*) "tds=", tds
n=n+1
if (n>10) exit
i = 1
inner: do
if (i > non) then
non = non +1
names(non) = trim(aname)
!ni = non
exit
end if
if (aname == names(i)) then
!ni = i
!cycle outer
exit inner
end if
i = i + 1
end do inner
end do middle
end do outer
write(*,*)
write(*,*) "Names:"
do i = 1,non
write(*,*) i, names(i)
end do
close(10)
close(20)
STOP
end program name_finder
TLDR; I am having trouble reading the data from the file shown at the top of each site after the names.
Suggestions? Thanks!
I hope the following is helpful. I have omitted any easily assumed declarations or any further data manipulation or writing to another file. The code is used just to read the data line by line.
character(150) :: word
read(fileunit, '(A)') word ! read the entire line
comma_ind = index(word,',') ! find the position of first comma
! Find the position of next comma
data_begin = index(word(comma_ind+1:),',')
! Save the name
thename = word(comma_ind+1:comma_ind+data_begin-1)
! Define next starting point
data_begin = comma_ind+data_begin
! Read the rest of the data
outer: do
if (word(data_begin+1:data_begin+1) == ',') then
! decide what to do when missing an entry
data_begin = data_begin + 1
cycle outer
else if (word(data_begin+1:data_begin+1) == ' ') then
! Missing last entry
exit outer
else
! Use it to find the length of current entry
st_ind = index(word(data_begin+1:),',')
if (st_ind == 0) then
! You reached the last entry, read it and exit
read(word(data_begin+1:), *) realData
exit outer
else
! Read current entry
read(word(data_begin+1: data_begin+st_ind-1),*) realData
end if
! Update starting point
data_begin = data_begin + st_ind
end if
end do outer
There could be a more elegant way to do it but I cannot think of any at the moment.

How to write output to a string in fortran?

I need to write a formated output to a string DTSTR. It use to work under layhe fortran but not gfortran
INTEGER*2 MON,DAY,YEAR,HR,MINUTE,SEC,HUND
CHARACTER DY*2
CHARACTER DTSTR*24
COMMON /RD/ DTSTR
...
...
WRITE(DTSTR,10)MON,DAY,YEAR,HR,MINUTE,DY,' ]'
10 FORMAT('[ ',I2,'-',I2.2,'-',I4,2X,I2,':',I2.2,1X,2A2)
it empty just a empty line. If i use following it correctly output. But i want to store this string. Is it possible to do that with gnu fortran.
WRITE(*,10)MON,DAY,YEAR,HR,MINUTE,DY,' ]'
update
I am trying to compile following file. I think the problem might be with the COMMON.
PROGRAM HELO
CALL DOTIME
WRITE(*,5700)DTSTR
5700 FORMAT(24X,A24/)
END
SUBROUTINE DOTIME
C
IMPLICIT NONE
INTEGER*2 MON,DAY,YEAR,HR,MINUTE,SEC,HUND
CHARACTER DY*2
CHARACTER DTSTR*24
COMMON /RD/ DTSTR
integer values(8)
call date_and_time(VALUES=values)
YEAR = values(1)
MON = values(2)
DAY = values(3)
HR = values(5)
MINUTE = values(6)
SEC = values(7)
HUND = values(8)
C =================================================
C
C Incompitable function => CALL GETDAT(YEAR,MON,DAY)
C Incompitable function => GETTIM(HR,MINUTE,SEC,HUND)
IF(HR .GE. 12)THEN
IF(HR .NE. 12)HR=HR-12
DY='PM'
ELSE
DY='AM'
ENDIF
WRITE(DTSTR,10)MON,DAY,YEAR,HR,MINUTE,DY,' ]'
10 FORMAT('[ ',I2,'-',I2.2,'-',I4,2X,I2,':',I2.2,1X,2A2)
RETURN
END
Hmm? It works just fine for me:
program testwrite
implicit none
INTEGER :: MON,DAY,YEAR,HR,MINUTE,SEC,HUND
CHARACTER(LEN=2) :: DY
CHARACTER(LEN=24) :: DTSTR
MON = 4
DAY = 27
YEAR= 2010
HR = 13
MINUTE = 27
SEC = 0
HUND = 0
DY ='WE'
WRITE(DTSTR,10)MON,DAY,YEAR,HR,MINUTE,DY,' ]'
10 FORMAT('[ ',I2,'-',I2.2,'-',I4,2X,I2,':',I2.2,1X,2A2)
print *,'<',trim(DTSTR),'>'
end program testwrite
gives
<[ 4-27-2010 13:27 WE ]>
just as one would expect. Works with several versions of gfortran I have kicking around.
Update: Yes, the problem is in your common block. The common block isn't declared in the main program. But really, it's much simpler and much, much better practice just to pass the string as an argument:
PROGRAM HELO
IMPLICIT NONE
CHARACTER(LEN=24) :: DTSTR
CALL DOTIME(DTSTR)
WRITE(*,5700)DTSTR
5700 FORMAT(24X,A24/)
END
SUBROUTINE DOTIME(DTSTR)
C
IMPLICIT NONE
INTEGER*2 MON,DAY,YEAR,HR,MINUTE,SEC,HUND
CHARACTER DY*2
CHARACTER(LEN=24), INTENT(OUT) :: DTSTR