文字と文字列

今日は文字と文字列について。
参考ページ:

 cf. 11. 文字、文字列 – もうひとつの Scheme 入門
 cf. 6.10 文字 – Gauche ユーザリファレンス
 cf. 6.12 文字列 – Gauche ユーザリファレンス

文字

文字のリテラルは #\ に続けて文字を書く。たとえば a という文字を表すには #\a とする。なんか変な感じ。

gosh> #\a
#\a

あと、いくつかの特殊文字などには名前がついている。名前は大文字と小文字を区別しない。

  • #\space
  • #\newline
  • #\return
  • #\tab
  • #\delete
  • #\null

以下、文字にかんする関数をいくつか。

(char? obj) は obj が文字なら真を返す。

gosh> (char? #\a)
#t

(char=? c1 c2) は文字が等しければ真を返す。

gosh> (char=? #\a #\a)
#t

(char->integer c) は文字を整数(ASCIIコード)に変換する。(integer->char n) はその逆。

gosh> (char->integer #\a)
97
gosh> (integer->char 97)
#\a

(char-alphabetic? c)(char-numeric? c)(char-whitespace? c)(char-upper-case? c)(char-lower-case? c) はそれぞれ、c がアルファベット、数字、空白文字、大文字、小文字のときに真を返す。

gosh> (char-alphabetic? #\a)
#t
gosh> (char-numeric? #\1)
#t
gosh> (char-whitespace? #\space)
#t
gosh> (char-upper-case? #\A)
#t
gosh> (char-lower-case? #\a)
#t

(char-upcase c)(char-downcase c) はそれぞれ、大文字、小文字に変換する。

gosh> (char-upcase #\a)
#\A
gosh> (char-downcase #\A)
#\a

文字列

文字列のリテラルは、たとえば “abc” みたいに ” でくくる。こっちは普通な感じ。

(string? s) は s が文字列なら真を返す。

gosh> (string? "foo")
#t

(string-length s) は文字列の長さ。

gosh> (string-length "foo")
3

(string=? s1 s2) は s1 と s2 が等しいとき真を返す。

gosh> (string=? "foo" "foo")
#t

(string-ref s idx) は s の idx番目の文字を返す。idx は0から。

gosh> (string-ref "abcde" 3)
#\d

(substring s start end) は start番目 から end – 1 番目の部分文字列を返す。Python のスライスと同じ要領だな。

gosh> (substring "abcde" 2 4)
"cd"

(string-append s1 s2) は文字列の連結。

gosh> (string-append "foo" "bar")
"foobar"

(string->list s)(list->string ls) は文字列とリストの変換。

gosh> (string->list "abc")
(#\a #\b #\c)
gosh> (list->string '(#\a #\b #\c))
"abc"

こんなところか。もっと詳しくは参考ページで。

練習問題

最後に練習問題をやっておこう。11. 文字、文字列 – もうひとつの Scheme 入門 より。

単語の初めを大文字にする関数 title-style を書いてください。

(define title-style
  (lambda (str)
    (letrec ((u (lambda (l acc)
      (cond
        ((null? l) (list->string (reverse acc)))
        ((char-whitespace? (car l)) (u (cdr l) (cons (car l) acc)))
        (else (d (cdr l) (cons (char-upcase (car l)) acc))))))
          (d (lambda (l acc)
            (cond
              ((null? l) (list->string (reverse acc)))
              ((char-whitespace? (car l)) (u (cdr l) (cons (car l) acc)))
              (else (d (cdr l) (cons (car l) acc)))))))
                (u (string->list str) '()))))

(print (title-style "one size fits all"))

実行結果:

^o^ > gosh title-style.scm
One Size Fits All