Как проверить на ввод строки? (Дьялог АПЛ) - PullRequest
0 голосов
/ 30 октября 2018

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

Также книга Мастеринг 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 ]

0 голосов
/ 30 октября 2018

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

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. Перед выводом введите ⎕←, чтобы упростить определение и повышение четкости.
 Happy;input;valid;values;N;N2;f;D
 ⎕←'Enter a Number'
 input←⍞
 (valid values)←⎕VFI input
 :If valid≡,1
 :AndIf values≡⌊values
     N←⊃values
     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 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'
                 ⎕←'**********************************'
             :EndIf
             :If N=1
                 ⎕←'**********************'
                 ⎕←'Yes!',N2,'is a happy number'
                 ⎕←'**********************'
             :EndIf
         :Until N=4
     :EndIf
 :Else
     ⎕←'You entered: ',input,' Enter an integer'
 :EndIf
0 голосов
/ 30 октября 2018

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

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

 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

Примечания

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

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

...