I need to handle C style ('0円'
delimited) strings from/to a socket and came up with this as a first attempt:
#lang racket
(require racket/tcp)
(define (read-c-str inp)
(define (read-to-zero acc)
(define b (read-byte inp))
(cond
[(equal? b 0) (bytes->string/utf-8 (apply bytes (reverse acc)))]
[else (read-to-zero (cons b acc))]))
(read-to-zero null))
(define (write-c-str val p)
(write-bytes (bytes-append (string->bytes/utf-8 val) (bytes 0)) p)
(flush-output p))
Writing is pretty simple, but I have the feeling I'm missing a more simple way to handle the accumulator there, and mainly looking for feedback on read-c-str
. I'm suspicious of having to reverse, making me think there is a better way.
Here was my second attempt which I'm not convinced is a better way:
(define (blist->string blist)
(bytes->string/utf-8 (foldr (lambda (inb l) (bytes-append l (bytes inb))) #"" blist)))
(define (read-c-str inp)
(define (read-to-zero acc)
(define b (read-byte inp))
(if (equal? b 0)
(blist->string acc)
(read-to-zero (cons b acc))))
(read-to-zero null))
1 Answer 1
I would accumulate bytes instead of integers.
(define (read-c-str inp)
(define (read-to-zero acc)
(define b (read-byte inp))
(if (equal? b 0)
(blist->string acc)
(read-to-zero (bytes-append acc (bytes b)))))
(read-to-zero #""))
And change blist->string
accordingly.
Edit: in this case blist->string
will become just bytes->string/utf-8
.
-
\$\begingroup\$ can you please point out where specifically I'm using integers? this code appears to be the same, just moved around. edit: nevermind, I see.. \$\endgroup\$user54495– user544952014年10月07日 19:39:15 +00:00Commented Oct 7, 2014 at 19:39
-
\$\begingroup\$ actually, looking at this again. I'm really not sure. Can you please specify where exactly I'm using an integer? \$\endgroup\$user54495– user544952014年10月08日 17:15:05 +00:00Commented Oct 8, 2014 at 17:15
-
\$\begingroup\$ You use
bytes
to convert from number to byte string. Andread-byte
actually returns numeric representation of the byte read. Try running the following code:(let ([ip (open-input-string "a")])(read-byte ip))
It will return 97, a number. Not a byte string#"a"
\$\endgroup\$Danil Gaponov– Danil Gaponov2014年10月09日 07:30:07 +00:00Commented Oct 9, 2014 at 7:30