Subject: Re: HELP, autolisp, newbie
Date: Fri, 12 Apr 1996 01:01:45 GMT
From: Vladimir Nesterovsky <vnestr@netvision.net.il>
Organization:
Newsgroups:
Message-ID:
References:

malcolm@foxbat.sur.uct.ac.za (Malcolm Robert Dingle) wrote:

>Hi all

>I am looking at using (read-line) to read in a line from the file. However
>this reads input as a string. If I then used (read) on the string the first
>value in the string would be returned as a int/float (in this example it
>would return 10) but I can't see how to read the other values (ie 30 and
>40). Is it not possible to tell it to read the second value in the string?

> I come from a C background where I
>am used to having more options for reading input from a file than I can
>count :-) so being able to find only a couple of commands to read from a
>file seems a little foreign to me.

Hello, You do have more options for input. Consider doing fgets() and then converting parts of string by atoi() etc { in C }. You can do the same in LISP with (setq line (read-line file)) and (atoi (substr line 1 5)), or (atof (substr line 7)) etc. Of course it's only good for file in fixed format, for free format you need to parse the string {like strtok() in C do}, breaking it on spaces {and/or commas etc} and converting the string into list of strings==tokens, then apply whatever function you want on elements of this list { these strings may represent INTs, REALs, STRs, SYMs etc} with MAPCAR or smtng. Here is general parsing function in LISP:

;;
;; (C.) 1996 by Vladimir Nesterovsky<vnestr@netvision.net.il>
;; USE THESE FUNCTIONS FOR ANY NON-PROFITABLE PURPOSE WHILE
;; KEEPING THIS NOTICE. NO WARRANTIES ARE GIVEN WHATSOEVER.
;;

;; strtol convert string of chars into list of 1-char strings (defun strtol ( s / lst c ) (repeat (setq c (strlen s)) (Setq lst (cons (substr s c 1) lst) c (1- c) )) lst )

;; helper function (defun strp(s)(and(='STR(type s))(/= s "")))

;; STRTOK - break strng on char if it's in chs (char-string). ;; Like "C" strtok() break string to tokens delimited by one ;; OR MORE chars. ;; parse free format -- no empty tokens -- ;; (strtok " 1,, 2, 3,")->{"1" "2" "3"} (defun strtok(strng chs / len c l s cnt chsl ) (setq chsl (strtol chs)) (setq len (strlen strng) s "" cnt (1+ len)) (while (> (setq cnt (1- cnt)) 0) (setq c (substr strng cnt 1)) (if (member c chsl) (if (strp s) (setq l (cons s l) s "") ) (setq s (strcat c s)) ) ) (if (strp s) (cons s l) l ) )

If you want to catch null tokens too, like "1,,3,4" -->> { "1" "" "3" "4" }, you'll need this:

;;STRPARSE FOR PARSING STRING (and keeping null tokens) (defun strparse(strng chs / len c l s chsl cnt );;delim==one-of-chs. (setq chsl (strtol chs)) (setq len (strlen strng) s "" cnt (1+ len)) (while (> (setq cnt (1- cnt)) 0) (setq c (substr strng cnt 1)) (if (member c chsl) (if (/= cnt len);; "1,2," -> ("1" "2") and not ("1" "2" "") (setq l (cons s l) s "") ) (setq s (strcat c s)) ) ) (cons s l) ;; ",1,2" -> ("" "1" "2") )

So now, armed with this string manipulation functions, you may (setq line (read-line file) lst (strtok line ", ") nums (mapcar 'atoi lst)) etc.

Possible improvements: do C_STRTOK() and C_STRPARSE() in ADS and export them to LISP from there. It must be much much faster.
Best wishes,
==Vladimir Nesterovsky  /LISP/C/C++/ADS.....
(defun str_rev(s)(apply 'strcat (reverse (strtol s))))

=Vladimir Nesterovsky   LISP/C/C++ etc
==(defun strf(s field)(vpn_printf "%.*s" field s))
Reini: Look also at http://xarch.tu-graz.ac.at/autocad/code/adesk/SDK2/STRING.LLB for similar and more string functions