Ошибка Плохой тип аргумента: fixnump: nil при вызове второй функции - PullRequest
1 голос
/ 17 апреля 2020

Я пытаюсь создать массив списков с элементами: Surname, Name и Age.

Вот мой код в 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)
 )

Проблема в том, что при попытке доступа ко второй функции выдается сообщение об ошибке:

Bad тип аргумента: fixnump: ноль.

Теперь я понятия не имею, где проблема на самом деле.

Есть идеи?

1 Ответ

1 голос
/ 17 апреля 2020

Ошибка:

; ошибка: неверный тип аргумента: fixnump: nil

Возникает, когда функции, для которой требуется целочисленный аргумент, предоставляется значение nil. Следовательно, эта ошибка возникает из-за вычисления второго из ваших двух itoa выражений:

(itoa (cdr (assoc 'v inreg)))

(Так как первое выражение itoa снабжается переменной n, которая не может быть nil).

Это означает, что следующее выражение возвращает nil:

(cdr (assoc 'v inreg))

Что означает, что один из списков ассоциаций в списке, который содержится в вашей глобальной переменной DP_DATA не содержит пунктирную пару с ключом v. Поэтому я бы предложил проверить значение, хранящееся в вашей глобальной переменной DP_DATA.


В сторону: обратите внимание, что initget не влияет на приглашение getstring - вы можете добиться того же эффекта, используя basi c while l oop, например:

(while (= "" (setq prenume (getstring "\nIntroduceti prenumele: ")))
    (princ "\nPlease enter a first name.")
)
(while (= "" (setq nume (getstring "\nIntroduceti numele: ")))
    (princ "\nPlease enter a surname.")
)

Вы можете учесть нулевые значения в списке ассоциаций, используя некоторую проверку ошибок basi c:

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

Приведенное выше вернет пустое имя / фамилию, если ее нет, и возраст 0, если его нет; Вы также можете вернуть ошибку, если эти значения отсутствуют, например:

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