MarcoW Posted February 21, 2011 Posted February 21, 2011 Today is one of those days... I can't find the problem. My goal: To read from an external file and get in return "a list of lists". My lisp: (defun Test (/ MyFile MyOpenFile Line AllMyFile) (setq MyFile "C:\\MyExternalFile.txt") (if MyFile (progn (setq MyOpenFile (open MyFile "r")) (setq AllMyFile nil) (while (setq Line (read (read-line MyOpenFile))) (setq AllMyFile (append AllMyFile (list Line))) ) (close MyOpenFile) ) ;_progn (alert "No external file found !!") ) (princ) ) ;_defun My External File: ("aName" "anAdress1" "SomeOtherData1") ("bName" "anAdress2" "SomeOtherData2") ("cName" "anAdress3" "SomeOtherData3") ("dName" "anAdress4" "SomeOtherData4") Analysis: I want to get this: (("aName" "anAdress1" "SomeOtherData1") ("bName" "anAdress2" "SomeOtherData2") ("cName" "anAdress3" "SomeOtherData3") ("dName" "anAdress4" "SomeOtherData4")) But it returns this: Command: (test) ; error: bad argument type: stringp nil I know this is because it tries to read an empty line, but I thought it would only read the line if the line is not NIL. Therefore the error "stringp nil". But having said that, what do I do wrong? It must be some minor issue. A sidenote: somehow I suspect the part "(read(read-line ..." since leaving out the first "read" does work. However, it returns a list full of \" wich I cannot use without parsing. Any help is very much appreciated, as always. Quote
Lt Dan's legs Posted February 21, 2011 Posted February 21, 2011 (edited) ------external file starts here--------- 1 "testing" "testing1" 2 "testing2" "testing3" --------ends here--------- (_read "file location") will return ((1 ("testing" "testing1")) (2 ("testing2" "testing3"))) (defun _read ( filename / fname line lst temp newlist ) (if (findfile filename) (progn (setq fname (open filename "r")) (while (setq line (read-line fname)) (if (not (wcmatch line "")) (setq lst (append (list line) lst)) ) ) (setq fname (close fname)) (if lst (foreach x (mapcar 'read lst) ;|Big thanks to Alanjt|; (if (numberp x) (setq temp (not (setq newlist (cons (list x temp) newlist)))) (setq temp (cons x temp)) ) ) ) (if newlist newlist (mapcar 'read lst) ) ) ) ) Edited February 21, 2011 by Lt Dan's legs Want to clarify Quote
MarcoW Posted February 21, 2011 Author Posted February 21, 2011 Thanks for the reply Lt Dan's Legs, but I have no clue what you mean Also I would like to understand why my lisp does not work without actually using a totally different lisp. Unless my lisp is totally wrong of course... Quote
Lt Dan's legs Posted February 21, 2011 Posted February 21, 2011 (defun _Test ( MyFile / MyOpenFile Line AllMyFile) (if (findfile MyFile) (progn (setq MyOpenFile (open MyFile "r")) (while (setq Line (read-line MyOpenFile)) (if (not (wcmatch line "")) (setq AllMyFile (append AllMyFile (list line))) ) ) (close MyOpenFile) ) ) AllMyFile ) try (_Test "C:\\MyExternalFile.txt") Quote
MarcoW Posted February 21, 2011 Author Posted February 21, 2011 I tried the routine and it returns this: ("(\"dName\" \"anAdress4\" \"SomeOtherData4\")" "(\"cName\" \"anAdress3\" \"SomeOtherData3\")" "(\"bName\" \"anAdress2\" \"SomeOtherData2\")" "(\"aName\" \"anAdress1\" \"SomeOtherData1\")") It should be like this: (("dName" "anAdress4" "SomeOtherData4") ("cName" "anAdress3" "SomeOtherData3")("bName" "anAdress2" "SomeOtherData2") ("aName" "anAdress1" "SomeOtherData1")) Tried it with the usage of the extra "read" and still get this error: ; error: bad argument type: stringp nil Basically the code works but when it gets to the end of the contents in the external file, it crashes. The code (read(read-line MyOpenFile))) cannot handle nil or "".... Even if it is in a while loop, it crashes. So obviously I am missing an important thingy but what?? Quote
Lt Dan's legs Posted February 21, 2011 Posted February 21, 2011 Sorry it took so long to repond read cannot handle nil simple test. Try (read nil) (defun _Test ( MyFile / MyOpenFile Line AllMyFile newlist temp) (if (findfile MyFile) (progn (setq MyOpenFile (open MyFile "r")) (while (setq Line (read-line MyOpenFile)) (if (not (wcmatch line "")) (setq AllMyFile (append (list line) AllMyFile )) ) ) (close MyOpenFile) (foreach x allmyfile (if (wcmatch (strcase x) "*NAME*") (setq temp (not (setq newlist (cons (cons x temp) newlist)))) (setq temp (cons x temp)) ) ) ) ) (if newlist newlist allmyfile) ) (_Test "C:\\MyExternalFile.txt") Quote
MarcoW Posted February 21, 2011 Author Posted February 21, 2011 No problem! At this moment I cannot acces my autocad but as soon as I can I will try THE code. Thanks for THE time. Message sent by phone sorry for mistakes. Quote
alanjt Posted February 21, 2011 Posted February 21, 2011 (defun _read (file / r l) (if (and (findfile file) (setq file (open file "R"))) (progn (while (setq r (read-line file)) (setq l (cons (read r) l))) (close file) (reverse l)) ) ) Quote
alanjt Posted February 21, 2011 Posted February 21, 2011 BTW, (append (list )) is much slower than (cons ) and using reverse in the end. Quote
MarcoW Posted February 22, 2011 Author Posted February 22, 2011 @ Lt Dan's legs: Thanks for your efforts, I can understand the problem now, indeed "read" cannot handle nil, tested with (read nil). I had some strange feelings with "read" from the beginning but it took away the \" symbols. Too bad I could not get there myself since I was close. (defun _read (file / r l) (if (and (findfile file) (setq file (open file "R"))) (progn (while (setq r (read-line file)) (setq l (cons (read r) l))) (close file) (reverse l)) ) ) @ Alanjt: Thank you for this code, I did not want to use a whole other approach because I wanted to learn what was wrong with my code. But after reading your code I was suprised how much shorter your code is and how easy to understand. BTW, (append (list )) is much slower than (cons ) and using reverse in the end. I have been reading this and this and find both are somewhat the same. At least if you read it, it looks the same. So why do you say it is faster using Cons instead of Append? Of course I have no doubt that you are not right :-) Anyway, I can move on now. Thanks to both you guys! Quote
Lt Dan's legs Posted February 22, 2011 Posted February 22, 2011 BTW, (append (list )) is much slower than (cons ) and using reverse in the end. Thanks for the tip Alan!! The speed is noticeable Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.