在球拍中从stdin读取输入的最佳方法是什么?
特别喜欢c ++中的cin
或c中的scanf
,我指的是我想要阅读的内容类型,然后返回。
答案 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-char
,read-string
,read-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 中不起作用。