Запрос данных у пользователя
Фактически все, что ниже, является продолжением статьи Код без ошибок. Хотелось бы поговорить насчет запроса у пользователя каких-то данных - строк, чисел, данных на экране и т.п.
Допустим, по ходу программы надо у пользователя запросить точку на экране. Классический вариант выглядит как
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 |
Я прошу прощения, что не совсем по теме, и не совсем во время. Но столкнулся с такой проблемой. Я хочу запросить строку/текст с пробелами с помощью getstring - (getsring T "\nВведитеттекст: ")
Всё с этим хорошо, но если пробел(ы) будет последним в ведённой строке, то после операции "обрубается" последний пробел. А мне надо , чтобы он тоже входил в состав текста.
В общем задача у меня объединять тексты с введёнными разделителями.
Например:
Введите текст №1: SF1
Введите разделитель №1: ,"здесь пробел"
Введите текст №2:
...
Итог должен быть: SF1, SF2.
Программу с запросом ввода текста и разделителей и склеивания всего вместе я написал , но как выяснилось в разделителях последний пробел съедается. Есть ли какое-нибудь простое решение этой задачи?
Странно. Только что проверил в ACAD2016 конструкцию вида
[cc lang="cadlisp"](setq a (getstring t "Введите текст : "))[/cc]
Пробелы не уничтожаются самостоятельно ни в начале, ни в конце (если надо, могу снять ролик и на screencast его выложить). Может быть, проблема именно в программе "склейки"?
Действительно странно. У меня обрезаются последние пробелы, прям как не значимые нули в числах с точкой. И пробелы я имею ввиду не надписи "Введите текст : ", а самого введённого текста.
Я был бы весьма признательным за видео ролик, чтобы убедиться что это моя уникальная "проблема"
Ха, прикольно... Если включен динамический ввод, то у меня тоже отрубаются пробелы. Я просто настолько привык его отключать сразу и навсегда, что даже забыл про такой вариант
В принципе, можно создать диалог, в котором и выполнять запрос данных. Ну или отключать дин.ввод (системная переменная DYNMODE и, возможно, DYNPROMPT).
В качестве идеи: если разделитель гарантированно символ, к примеру, запятой, и после него не менее гарантированно идет пробел, то я бы просто подставлял в функцию "склейки" эту пару символов. Возможно, это будет более удобно и просто.
Вот за это - огромное спасибо!
Действительно при отключении динамического ввода всё работает как надо. Вот только подозреваю, что не совсем будет так удобно - смотреть чисто на консоль.
Не совсем понял какой диалог вы предлагаете создать.
Да "на лету" прямо - и запрашивать там нужные параметры. Я приводил пример здесь: http://autolisp.ru/2010/03/15/dcl-dialogs-create/