Как проверить на ввод строки? (Дьялог АПЛ)

Я работал над этой функцией Happy практиковать контроль потока. Happy проверяет, является ли число счастливым числом. Я также пытался научиться обрабатывать ошибки. Итак, я попытался поймать, если пользовательский ввод не является целым числом. Особенно, если ввод - строка. Для этого я попытался включить скалярный тест здесь, но я не смог протестировать его в редакторе, потому что, если я пытаюсь ввести любые буквы без кавычек, я получаю, конечно, VALUE ERROR: Undefined name,

Также книга Mastering APL предупреждает об использовании Quad для ввода данных.

Как правильно проверить, является ли ввод строкой? Я предполагаю, что пользователь будет вводить буквы без кавычек.

(Я использую Dyalog APL 17.0)

(Я взял код о том, как разделить число на его цифры отсюда?)

Happy
 'Enter a Number'
 N←⎕
 N2←N
 :If N<0
     N←|N
     'You entered'N2
     'Only positive numbers can be happy'
     'We will check if'N'is happy'
     N2←N
 :EndIf
 f←10⊥⍣¯1⊢
 D←f N
 N←+/D×D
 ⍝:If 0≢⊃0⍴⊂N
 ⍝:OrIf N≢⌊N
 ⍝    'You entered: 'N'Enter an integer'
 ⍝    →0
 ⍝:EndIf
 :If N=1
     '***************'
     'Yes'N2'is happy!'
     '***************'
 :Else
     :While N≠1
         N←+/D×D
         D←f N
         N←+/D×D
         'N is:'N
         :If N=4
             '**********************************'
             'Sorry!'N2'is not a happy number'
             '**********************************'
             :Leave
         :EndIf
         :If N=1
             '**********************'
             'Yes!'N2'is a happy number'
             '**********************'
         :EndIf
     :EndWhile
 :EndIf

2 ответа

Решение

Обновленный ответ

Без лишних слов, вот предлагаемое решение:

 Happy;ok;N;N2
 'Enter a Number'
 ok←0
 :While ~ok
     N2←N←⍞  ⍝ N2=original input
     ok←∧/N∊⎕D,'¯.'  ⍝ allow high minus for negatives and decimal separator
     (~ok)/'Please enter numeric data!'
 :EndWhile
 N←2⊃⎕VFI N  ⍝ result of ⍞ will be text, so make it numeric
 N←⍬⍴N       ⍝ make it a scalar 
 :If N<0
     N←|N
     'You entered'N2
     'Only positive numbers can be happy'
     'We will check if'N'is happy'
     N2←N
 :EndIf
 f←10⊥⍣¯1⊢
 D←f N
 N←+/D×D

 :If N=1
     '***************'
     'Yes'N2'is happy!'
     '***************'
 :Else
     :While N≠1
         N←+/D×D
         D←f N
         N←+/D×D
         'N is:'N
         :If N=4
             '**********************************'
             'Sorry!'N2'is not a happy number'
             '**********************************'
             :Leave
         :EndIf
         :If N=1
             '**********************'
             'Yes!'N2'is a happy number'
             '**********************'
         :EndIf
     :EndWhile
 :EndIf

замечания

  • Legrand прав насчет того, чтобы не использовать использовать вместо. Это дает вам "непереведенную" строку, чтобы вы могли работать с ней. Использование системы для оценки пользовательского ввода (без учета ошибок) может открыть двери для всех видов атак. (Документация здесь)

  • я использовал ⎕VFI (я думаю, это специфическая для Dyalog системная функция), которая проверяет ввод. Это предпочтительнее который (опять же) может открыть двери...(Документация здесь])

Вы должны использовать (Ввод символов; документация), а не , даст вам буквальный текст, который ввел пользователь.

input←⍞

Вы можете использовать ⎕VFI (Проверка и исправление ввода; документация) по результату для проверки числового ввода. Это даст вам вектор из двух векторов. Первый является логическим и указывается для каждого "слова" в аргументе. Второй вектор числовой, содержащий одно число на слово. Неверные слова становятся нулем.

(valid values)←⎕VFI input

Поэтому, если вы ищете одно число, проверьте вектор достоверности, а затем вы можете проверить, что оно является целым числом:

:If valid≢,1
:OrIf values≢⌊values
    'You entered: 'N'Enter an integer'
    →0
:EndIf

Наконец вы можете извлечь N:

N←⊃values

Несколько не связанных советов

  1. Не забудьте локализовать свои переменные, перечислив их в верхней части, каждая из которых предшествует ;,
  2. использование :Else для остальной части программы вместо →0 чтобы избежать прыжков.
  3. Точно так же вы можете избежать прыжков с :Leave путем изменения :EndWhile в :Until N=4,
  4. Ваш код может быть легче читать, если вы изложите свои условия в позитивном ключе.
  5. Чтобы избежать нежелательных интервалов, объедините ваши выходные данные (с ,), а не прядение (сопоставление) его.
  6. Предшествовать выводу с ⎕← чтобы было легче заметить и повысить четкость.
 Счастливый; ввод; действительный; значения;N;N2;f;D
 ⎕← "Ввести число" ввод ←⍞
 (допустимые значения)←⎕Ввод VFI: если действительный≡,1:AndIf значения≡⌊значения N←⊃значения N2←N: Если N<0
         N←|N
         ⎕← "Вы ​​ввели",N2
         ⎕← "Счастливыми могут быть только положительные числа" ⎕ ← "Мы проверим, если", N, "счастлив" N2←N:EndIf
     f←10⊥⍣¯1⊢
     D←f N
     N←+/D×D: Если N=1
         ⎕←'***************'
         ⎕←'Да',N2,' счастлив!'
         ⎕←'***************': Остальное: Пока N≠1
             N←+/D×D
             D←f N
             N←+/D×D
             ⎕←'N есть:', N: Если N=4
                 ⎕←'**********************************'
                 ⎕←'Извините!',N2,'не является счастливым числом'
                 ⎕←'**********************************':EndIf: Если N=1
                 ⎕←'**********************'
                 ⎕←'Да!',N2,'является счастливым числом'
                 ⎕←'**********************':EndIf: До N=4:EndIf: Остальное ⎕ ←' Вы ввели: ', введите,' Введите целое число ': EndIf
Другие вопросы по тегам