Запрос данных у пользователя

Фактически все, что ниже, является продолжением статьи Код без ошибок. Хотелось бы поговорить насчет запроса у пользователя каких-то данных - строк, чисел, данных на экране и т.п.

Допустим, по ходу программы надо у пользователя запросить точку на экране. Классический вариант выглядит как

1
(getpoint "\nУкажите точку : " )

Немного расширенный вариант предварительно включает в себя работу с initget. Но все равно - если пользователь жмет Esc, то программа вывалит ошибку.
На самом деле предупредить подобное развитие событий элементарно:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(if (= (type (setq
               pt (vl-catch-all-apply
                    (function
                      (lambda ()
                        (getpoint "\nУкажите точку <Отмена> : ")
                        ) ;_ end of lambda
                      ) ;_ end of function
                    ) ;_ end of vl-catch-all-apply
               ) ;_ end of setq
             ) ;_ end of type
       'list
       ) ;_ end of =
  (princ "\nOK!")
  (princ "\nКосяк...")
  ) ;_ end of if

В результате любая попытка ввода некорректных данных (нажатие Enter или Esc) выведет на экран слово "Косяк..." :)
Запрос, например, целого числа (если есть вариант "по умолчанию") ненамного сложнее:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
(setq default 16)
(if (= (type (setq
               value
                (vl-catch-all-apply
                  (function
                    (lambda ()
                      (cond
                        ((getint (strcat "\nВведите число <" (itoa default) "> : ")
                                 ) ;_ end of getint
                         )
                        (t default)
                        ) ;_ end of cond
                      ) ;_ end of lambda
                    ) ;_ end of function
                  ) ;_ end of vl-catch-all-apply
               ) ;_ end of setq
             ) ;_ end of type
       'int
       ) ;_ end of =
  (princ "\nOK!")
  (princ "\nКосяк 2.")
  ) ;_ end of if

Аналогичным образом можно запросить расстояние, угол, строку - да вообще все что угодно :) Самое главное - все, что касается собственно запроса, прописывать внутри vl-catch-all-apply и не забывать проверять тип возвращаемой переменной. Иногда (особенно при запросе строк) надо проверять и значение:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
(setq default 16)
(if (= (type (setq
               value
                (vl-catch-all-apply
                  (function
                    (lambda ()
                      (cond
                        ((getstring (strcat "\nВведите число <" (itoa default) "> : ")
                                    ) ;_ end of getint
                         )
                        (t (itoa default))
                        ) ;_ end of cond
                      ) ;_ end of lambda
                    ) ;_ end of function
                  ) ;_ end of vl-catch-all-apply
               ) ;_ end of setq
             ) ;_ end of type
       'str
       ) ;_ end of =
  (princ value)
  (princ "\nКосяк 2.")
  ) ;_ end of if

Если сейчас в ответ на приглашение ответить нажатием Enter, то value примет значение пустой строки (""). Поэтому код запроса строки может быть таким:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
(setq default 16)
(if (= (type (setq
               value
                (vl-catch-all-apply
                  (function
                    (lambda ()
                      (cond
                        ((getstring (strcat "\nВведите число <" (itoa default) "> : ")
                                    ) ;_ end of getint
                         )
                        (t (itoa default))
                        ) ;_ end of cond
                      ) ;_ end of lambda
                    ) ;_ end of function
                  ) ;_ end of vl-catch-all-apply
               ) ;_ end of setq
             ) ;_ end of type
       'str
       ) ;_ end of =
  (progn
    (if (= value "") ; проверка значения
      (setq value (itoa default))
      ) ;_ end of if
    (princ value)
    ) ;_ end of progn
  (princ "\nКосяк 2.")
  ) ;_ end of if

Размещено в Код LISP · Метки: , ,



Комментарии

Есть 7 коммент. к “Запрос данных у пользователя”
  1. Кирилл пишет:

    Я прошу прощения, что не совсем по теме, и не совсем во время. Но столкнулся с такой проблемой. Я хочу запросить строку/текст с пробелами с помощью getstring - (getsring T "\nВведитеттекст: ")
    Всё с этим хорошо, но если пробел(ы) будет последним в ведённой строке, то после операции "обрубается" последний пробел. А мне надо , чтобы он тоже входил в состав текста.
    В общем задача у меня объединять тексты с введёнными разделителями.
    Например:
    Введите текст №1: SF1
    Введите разделитель №1: ,"здесь пробел"
    Введите текст №2:
    ...
    Итог должен быть: SF1, SF2.

    Программу с запросом ввода текста и разделителей и склеивания всего вместе я написал , но как выяснилось в разделителях последний пробел съедается. Есть ли какое-нибудь простое решение этой задачи?

  2. Кулик Алексей aka kpblc пишет:

    Странно. Только что проверил в ACAD2016 конструкцию вида
    [cc lang="cadlisp"](setq a (getstring t "Введите текст : "))[/cc]
    Пробелы не уничтожаются самостоятельно ни в начале, ни в конце (если надо, могу снять ролик и на screencast его выложить). Может быть, проблема именно в программе "склейки"?

  3. Кирилл пишет:

    Действительно странно. У меня обрезаются последние пробелы, прям как не значимые нули в числах с точкой. И пробелы я имею ввиду не надписи "Введите текст : ", а самого введённого текста.
    Я был бы весьма признательным за видео ролик, чтобы убедиться что это моя уникальная "проблема"

  4. Кулик Алексей aka kpblc пишет:

    Ха, прикольно... Если включен динамический ввод, то у меня тоже отрубаются пробелы. Я просто настолько привык его отключать сразу и навсегда, что даже забыл про такой вариант :)
    В принципе, можно создать диалог, в котором и выполнять запрос данных. Ну или отключать дин.ввод (системная переменная DYNMODE и, возможно, DYNPROMPT).

  5. Кулик Алексей aka kpblc пишет:

    В качестве идеи: если разделитель гарантированно символ, к примеру, запятой, и после него не менее гарантированно идет пробел, то я бы просто подставлял в функцию "склейки" эту пару символов. Возможно, это будет более удобно и просто.

  6. Кирилл пишет:

    Вот за это - огромное спасибо!
    Действительно при отключении динамического ввода всё работает как надо. Вот только подозреваю, что не совсем будет так удобно - смотреть чисто на консоль.
    Не совсем понял какой диалог вы предлагаете создать.

  7. Кулик Алексей aka kpblc пишет:

    Да "на лету" прямо - и запрашивать там нужные параметры. Я приводил пример здесь: http://autolisp.ru/2010/03/15/dcl-dialogs-create/

Поделитесь своим мнением


Я не робот.