如何测试字符串输入? (对话 APL)

How to test for string input? (Dyalog APL)

我正在研究这个函数 Happy 来练习控制流。 Happy 测试一个数字是否是快乐数字。我也在尝试学习错误处理。所以,我试图捕捉用户输入是否是整数以外的任何东西。特别是如果输入是一个字符串。为此,我尝试合并标量测试 here 但我无法在编辑器上对其进行测试,因为如果我尝试输入任何不带引号的字母,我当然会得到 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

更新答案

事不宜迟,这里有一个建议的解决方案:

 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 不使用 是正确的,请改用 。这会为您提供 "untranslated" 字符串,以便您可以使用它。使用该系统评估用户输入(没有错误捕获)可能会为各种攻击打开大门。 (文档 here

  • 我使用 ⎕VFI(我认为这是 Dyalog 特定的系统函数)来验证输入。这比 更可取,它(再次)可以打开门...(文档 here]

您应该使用 字符输入documentation)而不是 将为您提供用户输入的文字。

input←⍞

然后您可以对结果使用 ⎕VFI验证并修复输入documentation)来检查数字输入。它会给你一个包含两个向量的向量。第一个是布尔值,并为参数中的每个 "word" 指示。第二个向量是数字,每个单词包含一个数字。无效单词变为零。

(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. 同样,你可以通过将:EndWhile改为:Until N=4来避免:Leave跳转。
  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