Я не знаком с Фортраном, но мне пришлось использовать старый код моего советника, но он не работал, и я мог отследить его до минимального рабочего примера.
hello.f следует :
implicit none
character*200 rec
integer var,idum
real*4 rdum
call xparse('-t0',1,1,'required',rec,idum,rdum)
print *, rec
read(rec,'(i6)') var
print *, var
END
И extra.f выглядит следующим образом:
c------------------------------------------------------------------
subroutine xparse(cc,nth,ifo,req,carg,iarg,rarg)
c------------------------------------------------------------------
character*(*) cc,req,carg
character*256 rec
c
iver=0
lcc=len(cc)
na=iargc()
ith=0
do 100 ia=1,na
call getarg(ia,rec)
if(rec(1:15).eq.'-xparse_verbose') iver=1
lrec=ilen(rec,256)
if(lrec.eq.lcc) then
if(rec(1:lcc).eq.cc(1:lcc)) then
if(iver.eq.1)write(0,'(a,a)')'xparse ,parsing:',rec(1:lcc)
c
if(nth.le.0) then
iarg=1
return
endif
c
ith=ith+1
if(ith.eq.nth) then
c
if(ia.eq.na) then
write(0,*)'parse error : missing value for ',cc
endif
call getarg(ia+1,rec)
lrec=ilen(rec,256)
if(iver.eq.1)write(0,'(a,a)')'xparse, string:',rec(1:lrec)
if(ifo.eq.1) then
if(iver.eq.1)write(0,'(a,a)')'xparse, character:',rec(1:lrec)
carg=rec
else if(ifo.eq.2) then
s=gets(rec)
if(s.ge.0.0)iarg=s+0.1
if(s.lt.0.0)iarg=s-0.1
if(iver.eq.1)write(0,*)'xparse, integer:',iarg
else if(ifo.eq.3) then
rarg=gets(rec)
if(iver.eq.1)write(0,*)'xparse, real:',rarg
endif
return
c
endif
endif
endif
100 continue
c
if(req(1:8).eq.'required') then
write(0,*)'parse error : cant find required arg: ',cc
stop
endif
end
c------------------------------------------
real function gets(cc)
c------------------------------------------
c
c decodes integer or floating f format
c from character string
c
character*(*) cc
nn=len(cc)
c
gets=0.0
fak=1.
ief=0
l1=0
l2=0
do 200 i=1,nn
if(cc(i:i).eq.'e'.or.cc(i:i).eq.'E')ief=i
if(cc(i:i).eq.'d'.or.cc(i:i).eq.'D')ief=i
if(l1.eq.0.and.cc(i:i).ne.' ')l1=i
if(cc(i:i).ne.' ')l2=i
if(cc(i:i).eq.' '.and.l2.gt.0) goto 201
200 continue
201 continue
nn=l2
if(ief.gt.0) then
lex=l2-ief
iex=-9999999
if(lex.eq.1)read(cc(ief+1:l2),'(i1)',err=900) iex
if(lex.eq.2)read(cc(ief+1:l2),'(i2)',err=900) iex
if(lex.eq.3)read(cc(ief+1:l2),'(i3)',err=900) iex
if(lex.eq.4)read(cc(ief+1:l2),'(i4)',err=900) iex
if(lex.eq.5)read(cc(ief+1:l2),'(i5)',err=900) iex
if(iex.gt.-999999) then
if(iex.lt.0)fak=1./( 10.**(-iex) )
if(iex.gt.0)fak=10.**iex
else
write(0,*)'gets: cannot read ',cc
endif
nn=ief-1
endif
c
sig=1.
ss=0.
tt=1.
ip=0
do 100 l=1,nn
if(cc(l:l).ne.' ') then
if(cc(l:l).eq.'.') then
ip=1
else if(cc(l:l).eq.'-') then
sig=-1.
else
c read(cc(l:l),'(i1)',err=900) ii
ii=ichar(cc(l:l))-48
if(ii.lt.0.or.ii.gt.9) goto 109
if(ip.eq.0) then
ss=10.*ss+float(ii)
else
tt=0.1*tt
ss=ss+tt*float(ii)
endif
endif
endif
100 continue
109 continue
gets=ss*sig*fak
return
900 continue
write(0,*)' gets: error reading formatted integer:'
write(0,*)nn
write(0,'(a,a,a)')'$',cc,'$'
return
end
c-------------------------------------
integer function ilen(c,m)
c-------------------------------------
character*80 c
k=1
do 100 i=1,m
if(c(i:i).ne.' '.and.c(i:i).ne.char(0))k=i
100 continue
ilen=k
jlen=k
return
end
Если я это сделаю
gfortran hello.f extra.f
./a.out -t0 10800
Я получаю сообщение об ошибке
10800
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x10a01735c
#1 0x10a0166f3
#2 0x7fff7376cb5c
#3 0x10a15b340
#4 0x10a15bd2d
#5 0x10a15978f
#6 0x10a00c917
#7 0x10a00c9e5
Segmentation fault: 11
Эта функция чтения (?) Часто используется в коде для чтения введенных пользователем данных (например, sys.argv Python), но я не понимаю, почему она не работает.
Я использую GNU Fortran (Homebrew G CC 9.3.0_1) 9.3.0, MacOS Mojave 10.14.6.