This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
Re: TRIM and TRIM_LEN
- From: Ray Nachlinger <ray at ultramarine dot com>
- To: Daniel Kraft <d at domob dot eu>
- Cc: Fortran List <fortran at gcc dot gnu dot org>
- Date: Fri, 16 Jan 2009 12:33:02 -0600 (CST)
- Subject: Re: TRIM and TRIM_LEN
- References: <4970CD08.2070807@domob.eu>
On Fri, 16 Jan 2009, Daniel Kraft wrote:
> Hi,
>
> I've just written a CSV parser because I need to import data originating from
> MS Access into my MySQL database and doing so via CSV seems to be the best
> way. It is no very sophisticated code and probably not implemented very
> clever, but anyways my importer beats MS Access' CSV export by an order of
> magnitude; so gfortran's IO is surely not the worst possible :)
>
> On the other hand, to counteract the unknown-string-length-problem, I use
> strings with a fixed "buffer size" of 1024 or 256 characters for whole lines
> and CSV tokens read. On those, I then do TRIMs and concatenate them back to
> form SQL statements; and because TRIM (or TRIM_LEN for the matter) has to skip
> over all those 1024 blanks, profiling showed that I'm spending 30% of time in
> libgfortran's trim and another 30% in libgfortran's trim_len. (Comments on
> how to do this better welcome, though the situation is ok with me at the
> moment, I won't do much imports.)
The following has worked for me for years.
subroutine sfc_read(unit, ios,length,buf)
c
c@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
c@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
c@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
c
c --------------- sf_read ---------------
c
c.D NAME=sf_read
c.D This routine reads an array of characters from to UNIT.
c.d It treates any control character as white space.
c
c@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
c@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
c@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
c
c
c********************************************* no implicit
c
implicit none
c
c********************************************* externals
c
c
c********************************************* local variables
c
integer ios,length,end,unit,k,fgetc
character buf*(*)
c
c********************************************* initialize
c
length = 1
c
c********************************************* read
c
do 2100 k = 1, len(buf)
ios = fgetc(unit,buf(k:k) )
if(ios.ne.0) then
if(length.gt.1) then
ios = 0
go to 3000
else
go to 9000
endif
elseif( buf(k:k) .eq. char(10) ) then
go to 3000
else
length = k
endif
2100 continue
c
c********************************************* find end
c
3000 do 3100 end = length,1,-1
if(ichar(buf(end:end)).le.31 ) then
buf(end:end) = ' '
elseif(ichar(buf(end:end)).gt.127) then
buf(end:end) = ' '
elseif(buf(end:end).ne.' ') then
length = end
go to 9000
endif
3100 continue
length = 1
c
c********************************************* all done
c
9000 return
c
end