用球拍做输入的最佳方式?

时间:2011-11-14 10:05:14

标签: scheme racket

在球拍中从stdin读取输入的最佳方法是什么?

特别喜欢c ++中的cin或c中的scanf,我指的是我想要阅读的内容类型,然后返回。

4 个答案:

答案 0 :(得分:8)

你可以做任何你想做的事情......在低级别,我建议(读取线)和(读取字节)。对于更高级别的处理(例如scanf),我建议在输入上进行正则表达式匹配。例如

(regexp-match #px" *([0-9]+)" (current-input-port))

答案 1 :(得分:6)

read-line很简单。要在Unix和Windows之间移植,需要额外的选项。

(read-line (current-input-port) 'any)
  

转换后检测到返回和换行符   在文本模式下读取文件时自动执行。对于   例如,在Windows上以文本模式读取文件会自动更改   返回换行组合到换行符。因此,当文件是   在文本模式下打开,'换行通常是适当的读取线   模式。

因此,当输入端口不是文件(标准输入)时,任何都需要是可移植的。

测试程序:

#lang racket
(let loop ()
    (display "Input: ")
    (define a (read-line (current-input-port) 'any))
    (printf "input: ~a, length: ~a, last character: ~a\n"
        a
        (string-length a)
        (char->integer (string-ref a (- (string-length a) 1))))
    (loop))

在Windows中,将(read-line (current-input-port) 'any)替换为(read-line),看看会发生什么。

答案 2 :(得分:2)

我将read程序用于一般情况。如果事先知道要读取的数据类型,请使用read-charread-stringread-bytes

另外,请查看this实现以读取格式化输入 - 在Scheme中scanf

答案 3 :(得分:0)

这是在 Racket Scheme 中逐行处理的基础。它不会将输入行拆分为多个单词,也不会键入输入,但这似乎是放置它的好地方。

(define (get)
  (read-line (current-input-port)))

(define (put . vs)
  (for-each display vs)
  (displayln ""))

(define (sed fn)
  (let ((line (get)))
    (if (not (eof-object? line))
      (begin
        (fn line)
        (sed fn))
      'true)))

(sed (lambda (line)
  (put "Hello, " line)))

这是一个可以分割输入,也可以对 CSV 进行编码以进行良好测量的方法。

(define (get)
  (read-line (current-input-port)))

(define split string-split)
(define sep ",")
(define enc identity)

(define (enc-csv s)
  (string-append "\"" (string-replace s "\"" "\"\"") "\""))
(define enc enc-csv)

(define (put . vs)
  (displayln (string-join (map enc vs) sep)))

(define (sed fn)
  (let ((line (get)))
    (if (not (eof-object? line))
      (begin
        (fn line)
        (sed fn))
      'true)))

(sed (lambda (line)
  (apply put (split line))))

这适用于 Racket。我不确定其中有多少是特定于 Racket 的。它似乎在 Chicken 或 Guile 中不起作用。