Как увеличить переменную в Лиспе
Вот проблема в коде:
(foreach n l_pt
(write-line
(strcat "sommet" str_sep
(itoa (setq (nbs (+1 nbs )))) str_sep
(rtos (car n) 2 2) str_sep
(rtos (cadr n) 2 2) str_sep
(strcat "2") str_sep
(strcat "borne")
)
f_open
)
)
;;(write-line "" f_open)
У меня есть такие файлы на выходе:
Sommets;;
Тип;Num;X;Y;Precison; Природа
Sommet;1;1532292,16;3214140,11; 2; Borne
Sommet;2;1532287,08;3214140,60;2; Borne
Sommet;1;1532291,45;3214136,43; 2; Borne
Sommet;2;1532286,50; 3214135,87;2; Borne
Sommet;1;1532287,08;3214140,60;2; Borne
Как вы уже догадались, проблемной частью является "Num", который не работает, как задумано, увеличивается.
Я понял, что это такая строка: " (itoa (setq (nbs (+1 nbs)))) str_se" не работает, как предполагалось, но я не знаю почему. Я пытался переключить его на (setq (nbs (+ 1 nbs))), но он тоже не работает.
Есть ли у вас идеи, откуда это идет?
2 ответа
Я думаю, что проблема в том, что у вас одна скобка. Или что вам нужно инициализировать nbs
вне повторения. Это зависит от того, как вы хотите, чтобы это работало.
Похоже, ваш код (значительно упрощенный) выглядит так:
;; Stuff before the problem
(repeat (sslength js)
;; (setq....)
(setq nbs 0)
;;; Lots of stuff
(foreach n l_pt
;; The printing code including...
(setq nbs (+ 1 nbs))
)
)
Как видите, вы устанавливаете nbs
в 0
каждый раз, когда вы проходите через repeat
цикл, а затем добавление 1
к этому позже.
Похоже, вы хотели разделить эти петли - repeat
пока не закончится расчет информации, а затем foreach
распечатать весь список l_pt
,
На мой взгляд, вы добавляете только 1 строку информации l_pt
каждый раз через большой repeat
цикл и только печать, что один элемент из foreach
заявление.
Перемещение скобок даст вам это:
(repeat (sslength js)
;;...
(setq nbs 0)
;;...
)
(foreach n l_pt
;;...
(setq nbs (+ 1 nbs))
)
Вы также можете разместить (setq nbs 0)
вне повторного цикла. Это, вероятно, было бы лучше в любом случае, чтобы было ясно, что вы делаете, и нет необходимости инициализировать его 5+ раз...
Кроме того, это показывает, почему стоит четко разделить присвоения переменных. Они могут потеряться в конце долгого (setq
) заявление:
;; Do this,
(setq sentence "This is one or more variable assignments."
number 200)
;; or this,
(setq sentence "This is one or more variable assignments.")
(setq number 200)
;; not this.
(setq sentence "This is one or more variable assignments." number 200)
В любом случае, любой из этих вариантов должен получить ваш счетчик nbs
снова работает
Надеюсь, это поможет!
PS Просто чтобы помочь с обсуждением (+1 nbs) в комментариях выше, в AutoLISP все правильно и эквивалентно:
(+ 1 nbs)
(+ nbs 1) ;; Order is not important for addition
(+ nbs 1 0 0 0) ;; Any number of values can be added
(1+ nbs) ;; The typical way to increment a value
;; (1+ is a function that returns the value + 1)
Это должно быть что-то особенное для AutoLISP. Я говорю это потому, что этот код (адаптированный к Common Lisp, как вы увидите)
(defun foo (l_pt)
(let ((str_sep ";")
(nbs 0))
(mapcar #'(lambda (n) (write-line (strcat (list "sommet" str_sep
(itoa (setq nbs (+ 1 nbs))) str_sep
(rtos (car n) 2 2) str_sep
(rtos (cadr n) 2 2) str_sep
(strcat "2") str_sep
(strcat "borne")))
))
l_pt)))
(defun rtos (a b c) (strcat a))
(defun strcat (string-designators)
(with-output-to-string (strcat)
(cond ((listp string-designators)
(mapcar #'(lambda (s) (princ s strcat)) string-designators))
(t (princ string-designators strcat)))))
(defun itoa (i) (write-to-string i))
для этого выражения:
(foo '((x y) (a b) (aa bb)))
производит этот вывод:
sommet;1;X;Y;2;borne
sommet;2;A;B;2;borne
sommet;3;AA;BB;2;borne
По общему признанию, мне пришлось изменить многие вещи, чтобы приспособить элементы AutoLISP, которых нет в Common Lisp, возможно, наиболее значимым из которых является то, что я не написал эквивалент foreach (потому что нет никакого способа узнать, что я бы повторил его идиосинкразии), но тем не менее это как минимум появляется setq
делает то, что вы ожидаете.