[TOC=2]
## 11.1 简介
我只介绍了表和数,因为它们在Scheme中最为常用。然而,Scheme也有像**字符(Character)**、**字符串(String)**、**符号(Symbol)**、**向量(Vector)**等的其它数据类型,我将在11到14章节中介绍它们。
## 11.2 字符
在某个字符前添加`#\`来表明该物是一个字符。例如,`#\a`表示字符a。字符`#\Space`、`#\Tab`、`#\Linefeed`和`#\Return`分别代表空格(Space)、制表符(Tab),Linefeed和返回(Return)。R5RS中定义了下面的与字符相关的函数。
`(char? obj)`
如果obj是一个字符则返回`#t`。
`(char=? c1 c3)`
如果c1和c2是同一个字符的话则返回`#t`。
`(char->integer c)`
将c转化为对应的整数(字符代码,character code)。示例:`(char->integer #\a) => 97`
`(integer->char n)`
该函数将一个整数转化为对应的字符。
`(char<? c1 c2)`
`(char<= c1 c2)`
`(char> c1 c2)`
`(char>= c1 c2)`
这些函数用于比较字符。实际上,这些函数比较的是字符代码的大小。例如,`(char<? c1 c2)`等同于`(< (char->integer c1) (char->integer c2))`
`(char-ci=? c1 c2)`
`(char-ci<? c1 c2)`
`(char-ci<=? c1 c2)`
`(char-ci>? c1 c2)`
`(char-ci>=? c1 c2)`
这些比较函数对大小写不敏感。
`(char-alphabetic? c)`
`(char-numeric? c)`
`(char-whitespace? c)`
`(char-upper-case? c)`
`(char-lower-case? c)`
这些函数分别用于检测字符c是否为字母、数字、空白符、大写字母或小写字母。
`(char-upcase c)`
`(char-downcase c)`
这些函数分别返回字符C对应的大写或小写。
## 11.3 字符串
字符串通过两个闭合的双引号表示。例如,”abc”表示字符串abc。R5RS定义了下面的函数。
`(string? s)`
如果`s`是一个字符则返回`#t`。
`(make-string n c)`
返回由`n`个字符`c`组成的字符串。参数`c`可选。
`(string-length s)`
返回字符串`s`的长度。
`(string=? s1 s2)`
如果字符串`s1`和`s2`相同的话则返回`#t`。
`(string-ref s idx)`
返回字符串`s`中索引为`idx`的字符(索引从0开始计数)。
`(string-set! s idx c)`
将字符串`s`中索引为`idx`的字符设置为`c`。
`(substring s start end)`
返回字符串`s`从`start`开始到`end-1`处的子串。例如`(substring "abcdefg" 1 4) => "b c d"`
`(string-append s1 s2 ...)`
连接两个字符串`s1`和`s2`
`(string->list s)`
将字符串`s`转换为由字符构成的表。
`(list->string ls)`
将一个由字符构成的表转换为字符串。
`(string-copy s)`
复制字符串`s`。
> 练习1
>
> 编写一个函数`title-style`,该函数用于将每个单词的首字母大写。
>
>
>
>
>
> ~~~
> (title-style "the cathedral and the bazaar")
> ;⇒ "The Cathedral And The Bazaar"
> ~~~
>
>
>
>
## 11.4 小结
本章讲解了字符和字符串。下章我将讲解符号。符号是Lisp/Scheme中的一种字符型数据类型。使用这种数据类型,可以对文本进行快速操作。
## 11.5 习题解答
### 11.5.1 练习1
先将字符串转化为表,将空格之后的字符大写,最后将表转换会字符串。【译注:原文似有误。】
~~~
(define (identity x) x)
(define (title-style str)
(let loop ((ls (string->list str))
(w #t)
(acc '()))
(if (null? ls)
(list->string (reverse acc))
(let ((c (car ls)))
(loop (cdr ls)
(char-whitespace? c)
(cons ((if w char-upcase identity) c) acc))))))
;;; Another answer, You can assign caps to the string.
(define (title-style str)
(let ((n (string-length str)))
(let loop ((w #t) (i 0))
(if (= i n)
str
(let ((c (string-ref str i)))
(if w (string-set! str i (char-upcase c)))
(loop (char-whitespace? c) (1+ i)))))))
(title-style "the cathedral and the bazaar")
;⇒ "The Cathedral And The Bazaar"
~~~