2011-03-29 89 views
3

我意識到這可能是一個非常愚蠢的問題,但我不知道爲什麼這不是工作,我幾乎放棄了。基本上我想:獲取標準輸入並將其作爲字符串存儲在lisp中

(setq answer (string (read))) 

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

(setq answer (read)) 

當我嘗試評估

(if (stringp answer) 
    (princ "works") 
    (princ "failed")) 
任何的

上述嘗試它永遠是失敗的。

我在做什麼錯?

回答

20

或者你可以只是做:

(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]> 
5

開始新的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,但寫信給它,如果它是streamstringfill-pointer。在其Documentation看看,你會看到:

格式目的地控制串 &休息ARGS =>結果

[...]

目的地---零, t,流或具有填充指針的字符串 。

[...]

格式是產生很好 格式化文本,製作好看 的消息,等有用。格式可以 生成並返回一個字符串或輸出 到目的地。

如果目標是字符串,流, 或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" :)它們只是幫助解釋代碼失敗原因的示例。

另一件事我忘了說的是,你應該記住,那就變量頂層setq不是與defvardefparameter一般都在什麼,但在REPL涉足避免的,因爲其後果是不確定的定義。而且,這些變量按照慣例被包裹在星號(也稱爲耳罩)中,以防止特殊詞彙與詞彙範圍變量混淆導致的錯誤。

相關問題