I want to parse the following string:
"0:72.00,1:73.00,2:74.00"
I want to break the string up into six numbers. The following C code fragment
using sscanf does the trick for me:
const char f[] = "0:72.00,1:73.00,2:74.00";
int i[3];
float d[3];
sscanf(f, "%d:%f,%d:%f,%d:%f", &i[0], &d[0], &i[1], &d[1], &i[2], &d[2]);
How do I do the equivalent thing in lisp? I ended up doing the following, but
there's got to be a better way right?
(setf ans "0:72.0,1:73.0,2:74.0")
;; substitute commas and colons with spaces
(setf ans2 (substitute #\space #\: (substitute #\space #\, ans)))
(setf i-array (make-array 3))
(setf d-array (make-array 3))
(with-input-from-string
(s ans2)
(dotimes
(i 3)
(setf (aref i-array i) (read s))
(setf (aref d-array i) (read s))
))
From: Thomas A. Russ
Subject: Re: newbie question - lisp equivalent of C's scanf?
Date:
Message-ID: <ymibuiyi9sw.fsf@hobbes.isi.edu>
In article <...> ···@telerobotics.jpl.nasa.gov (David Lim) writes:
>
> I want to parse the following string:
>
> "0:72.00,1:73.00,2:74.00"
>
> ...
> How do I do the equivalent thing in lisp? I ended up doing the following, but
> there's got to be a better way right?
The better way involves actually using a different input form. One that
conforms more closely to lisp syntax. Then it becomes trivial.
(Of course it is possible that the data string is created externally.
In that case, you really are forced to either do what you are doing or
to write your own scanf-like pattern matcher. I wonder if something
like that already exists in the archives?)
Another variant is to change the lisp reader's syntax table so that you
can just use the lisp reader.
> (setf ans "0:72.0,1:73.0,2:74.0")
> ;; substitute commas and colons with spaces
> (setf ans2 (substitute #\space #\: (substitute #\space #\, ans)))
> (setf i-array (make-array 3))
> (setf d-array (make-array 3))
> (with-input-from-string
> (s ans2)
> (dotimes
> (i 3)
> (setf (aref i-array i) (read s))
> (setf (aref d-array i) (read s))
> ))
Lisp-like solution:
(with-input-from-string (s "(0 72.0) (1 73.0) (2 74.0)")
(dotimes (i 3)
(let ((v (read s)))
(setf (aref i-array i) (first v))
(setf (aref d-array i) (second v)))))
Of course yet another possibility involves changing (a copy of) the
readtable so that ":" and "," are whitespace characters:
;; Setup a new readtable:
(defvar *parsing-readtable* (copy-readtable))
(set-syntax-from-char #\, #\Space *parsing-readtable*)
(set-syntax-from-char #\: #\Space *parsing-readtable*)
;; Use it:
(let ((*readtable* *parsing-readtable*))
(with-input-from-string (s "0:72.00,1:78.5,2:99.6")
(dotimes (i 3)
(let ((v (read s)))
(setf (aref i-array i) (first v))
(setf (aref d-array i) (second v))))) )
--
Thomas A. Russ, USC/Information Sciences Institute ···@isi.edu
>>>>> "tar" == Thomas A Russ <···@ISI.EDU> writes:
tar> In article <...> ···@telerobotics.jpl.nasa.gov (David Lim) writes:
>>
>> I want to parse the following string:
>>
>> "0:72.00,1:73.00,2:74.00"
>>
>> ...
>> How do I do the equivalent thing in lisp? I ended up doing the following, but
>> there's got to be a better way right?
tar> The better way involves actually using a different input form. One that
tar> conforms more closely to lisp syntax. Then it becomes trivial.
I work with David, and the input form is forced from outside. Coming across a
socket in fact.
tar> (Of course it is possible that the data string is created externally.
tar> In that case, you really are forced to either do what you are doing or
tar> to write your own scanf-like pattern matcher. I wonder if something
tar> like that already exists in the archives?)
That is a good question. I have poked around the CMU archives, and found
nothing.
Anyone care to guess why CL has printf, (format), but not scanf?
Surely someone has had to deal with structured input text. Anyone willing to
share their scanf code?
Thanks,
Don
Don Erway ······@ndc.com
NDC Systems 818-939-3847
5413 N. Irwindale Ave Fax:939-3870
Irwindale, CA, 91706
In article <···················@alumnae.ndc.com> ······@ndc.com (D. Erway) writes:
Anyone care to guess why CL has printf, (format), but not scanf?
Surely someone has had to deal with structured input text. Anyone willing to
share their code?
Thanks,
Don
SLIB library has scanf (scanf.scm) in Scheme. Probably it will
not be very difficult to rewrite in CL. Check out
http://www-swiss.ai.mit.edu/~jaffer/SCM.html