【问题标题】:getting standard input and storing it as a string in lisp获取标准输入并将其作为字符串存储在 lisp 中
【发布时间】:2011-03-29 05:22:09
【问题描述】:

我意识到这可能是一个非常愚蠢的问题,但我不知道为什么这不起作用,我几乎放弃了。基本上我试过了:

(setq answer (string (read)))

(setq answer 0)
(format answer "~s" (read))

(setq answer (read))

当我尝试评估时

(if (stringp answer) 
    (princ "works")
    (princ "failed"))

在上述任何尝试中,它总是失败。

我做错了什么?

【问题讨论】:

    标签: string lisp common-lisp stdin


    【解决方案1】:

    或者你可以这样做:

    (setq answer (read-line))
    

    这会给你一个字符串。

    [1]> (setq answer (read))
    3
    3
    [2]> (type-of answer)
    (INTEGER 0 16777215)
    [3]> (setq answer (read-line))
    3
    "3"
    [4]> (type-of answer)
    (SIMPLE-BASE-STRING 1)
    [5]>
    

    【讨论】:

      【解决方案2】:

      开始一个新的 REPL,然后尝试检查每个步骤的返回值:

      T1> (read)
      foo
      FOO
      T1> (read)
      1
      1
      T1> (type-of (read))
      foo
      SYMBOL
      T1> (type-of (read))
      1
      BIT
      

      现在请注意,STRING 不适用于所有输入类型:

      T1> (string 'foo)
      "FOO"
      T1> (string 1)
      

      还要注意,与setq 不同,(format foo ...) 不会设置 foo,但如果它是stream 或带有@987654323 的string,则写入它@。看看它的Documentation,你会看到:

      格式化目标控制字符串 &rest args => 结果

      [...]

      destination---nil, t, a stream, or a 带有填充指针的字符串。

      [...]

      格式对于很好地制作很有用 格式化文本,产生好看的 消息等。格式可以 生成并返回字符串或输出 到目的地。

      如果目的地是一个字符串,一个流, 或 t,则结果为零。 否则,结果为字符串 包含“输出”。

      试试这样:

      T1> (setq *answer*
                (with-output-to-string (s)
                  (format s "~s" (read))))
      1
      "1"
      T1> *answer*
      "1"
      

      或者像这样:

      T1> (setq *answer* (make-array 20 :element-type 'character :fill-pointer 0))
      ""
      T1> (format *answer* "~s" (read))
      1
      NIL
      T1> *answer*
      "1" 
      

      这些是我能在您的代码中找到的唯一相关错误。这肯定会在每个符合要求的 CL 中返回 "works"(您也可以使用 prin1-to-string):

      T1> (defvar *answer*)
      *ANSWER*
      T1> (setq *answer* (format nil "~s" (read)))
      1
      "1"
      T1> (if (stringp *answer*)
              (princ "works")
              (princ "failed"))
      works
      "works"
      

      除非你在一个混乱的包中(在评估你的代码之前尝试(in-package cl-user)),或者重新定义基本功能,否则这将起作用。给出一些更准确的错误描述,如果还是不行的话。

      ED:

      读过比尔的回答,他正确指出 read-line 是一个更简短的解决方案,我应该提一下,我并没有试图在我的回答中展示最好、最简洁或最惯用的方法,而那些会取决于你真正想做的事情。 (最短的可能解决方案是"works" :) 它们只是有助于解释代码失败原因的示例。

      我忘了说的另一件事是,您应该记住,除了涉足 REPL 之外,通常要避免在未使用 defvardefparameter 定义的变量上的顶级 setqs,因为后果是不确定的。此外,按照惯例,这些变量用星号(也称为 earmuffs)包裹,以防止由于混淆特殊变量和词法范围变量而导致的错误。

      【讨论】:

        猜你喜欢
        • 2014-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多