Jump to content

Lisp to read from external file crashes, why??


Recommended Posts

Posted

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.

Posted (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 by Lt Dan's legs
Want to clarify
Posted

Thanks for the reply Lt Dan's Legs, but I have no clue what you mean :unsure:

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...

Posted

 
(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")

Posted

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??

Posted

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")

Posted

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.

Posted
(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))
 )
)

Posted

BTW, (append (list )) is much slower than (cons ) and using reverse in the end.

Posted

@ 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!

Posted
BTW, (append (list )) is much slower than (cons ) and using reverse in the end.

Thanks for the tip Alan!! The speed is noticeable

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...