Reputation: 151
I'm trying to create an array of lists with its elements being: Surname
, Name
and Age
.
Here is my code in AutoLISP:
(defun C:DP_ADINREG ( / prenume nume varsta inreg)
(initget 1)
(setq prenume (getstring "\nIntroduceti prenumele: "))
(initget 1)
(setq nume (getstring "\nIntroduceti numele: "))
(initget 7)
(setq varsta (getint "\nIntroduceti varsta: "))
(setq inreg (list (cons 'pn prenume) (cons 'nf nume)
(cons 'v varsta))
DP_DATA (append DP_DATA (list inreg))
)
(princ)
)
(defun C:DP_LISTARE ( / curent inreg n)
(setq curent DP_DATA
n 1)
(while curent
(setq inreg (car curent))
(princ (strcat "\nInregistrarea #" (itoa n)
": " (cdr (assoc 'pn inreg))
", " (cdr (assoc 'nf inreg))
". Varsta " (itoa (cdr (assoc 'v inreg)))
)
)
(setq curent (cdr curent)
n (1+ n)
)
)
(princ)
)
Problem is, when trying to access the second function, it gives me an error called:
Bad argument type : fixnump : nil.
Now I have no idea where the problem actually is.
Any ideas?
Upvotes: 1
Views: 1497
Reputation: 16035
The error:
; error: bad argument type: fixnump: nil
Arises when a function requiring an integer argument is supplied with a value of nil
. Hence, this error is arising from the evaluation of the second of your two itoa
expressions:
(itoa (cdr (assoc 'v inreg)))
(Since the first itoa
expression is being supplied with the variable n
, which cannot be nil
).
This implies that the following expression returns nil
:
(cdr (assoc 'v inreg))
Which implies that one of the association lists within the list held by your global variable DP_DATA
does not contain a dotted pair with key v
. I would therefore suggest checking the value held by your global variable DP_DATA
.
Aside: note that initget
has no effect on a getstring
prompt - you can achieve the same effect using a basic while
loop, e.g.:
(while (= "" (setq prenume (getstring "\nIntroduceti prenumele: ")))
(princ "\nPlease enter a first name.")
)
(while (= "" (setq nume (getstring "\nIntroduceti numele: ")))
(princ "\nPlease enter a surname.")
)
You can account for null values in your association list using some basic error checking:
(defun C:DP_ADINREG ( / prenume nume varsta )
(while (= "" (setq prenume (getstring "\nIntroduceti prenumele: ")))
(princ "\nPlease enter a first name.")
)
(while (= "" (setq nume (getstring "\nIntroduceti numele: ")))
(princ "\nPlease enter a surname.")
)
(initget 7)
(setq varsta (getint "\nIntroduceti varsta: ")
DP_DATA (cons (list (cons 'pn prenume) (cons 'nf nume) (cons 'v varsta)) DP_DATA)
)
(princ)
)
(defun C:DP_LISTARE ( / n )
(setq n 0)
(foreach lst (reverse DP_DATA)
(princ
(strcat
"\nInregistrarea #" (itoa (setq n (1+ n)))
": " (cond ((cdr (assoc 'pn lst))) (""))
", " (cond ((cdr (assoc 'nf lst))) (""))
". Varsta " (itoa (cond ((cdr (assoc 'v lst))) (0)))
)
)
)
(princ)
)
The above will return a blank first name/surname where not present, and an age of 0
where not present; you could alternatively return an error if these values are not present, e.g.:
(defun C:DP_LISTARE ( / n nf pn v )
(setq n 1)
(foreach lst (reverse DP_DATA)
(if
(and
(setq pn (cdr (assoc 'pn lst)))
(setq nf (cdr (assoc 'nf lst)))
(setq v (cdr (assoc 'v lst)))
)
(princ (strcat "\nInregistrarea #" (itoa n) ": " pn ", " nf ". Varsta " (itoa v)))
(princ (strcat "\nMissing data for item " (itoa n)))
)
(setq n (1+ n))
)
(princ)
)
Upvotes: 1