6.6. Strings


6.6. Strings

Strings are sequences of characters and are typically used as messages or character buffers. Scheme provides operations for creating strings, extracting characters from strings, obtaining substrings, concatenating strings, and altering the contents of strings.

A string is written as a sequence of characters enclosed in double quotes, e.g., "hi there". A double quote may be introduced into a string by preceding it by a backward slash, e.g., "two \"quotes\" within". A backward slash may also be included by preceding it with a backward slash, e.g., "a \\slash".

Strings are indexed by exact nonnegative integers, and the index of the first element of any string is 0. The highest valid index for a given string is one less than its length.

(string=? string1 string2 string3 ...)

procedure

(string<? string1 string2 string3 ...)

procedure

(string>? string1 string2 string3 ...)

procedure

(string<=? string1 string2 string3 ...)

procedure

(string>=? string1 string2 string3 ...)

procedure

returns: #t if the relation holds, #f otherwise

As with =, <, >, <=, and >=, these predicates express relationships among all of the arguments. For example, string>? determines if the lexicographic ordering of its arguments is monotonically decreasing.

The comparisons are based on the character predicates char=?, char<?, char>?, char<=?, and char>=?. Two strings are lexicographically equivalent if they are the same length and consist of the same sequence of characters according to char=?. If two strings differ only in length, the shorter string is considered to be lexicographically less than the longer string. Otherwise, the first character position at which the strings differ determines which string is lexicographically less than the other, according to char<?.

The ANSI/IEEE standard includes only two-argument versions of these procedures. The more general versions are mentioned in the Revised5 Report.

Two-argument string=? may be defined as follows.

 (define string=?    (lambda (s1 s2)       (let ((n (string-length s1)))          (and (= (string-length s2) n)               (let loop ((i 0))                 (or (= i n)                     (and (char=? (string-ref s1 i) (string-ref s2 i))                          (loop (+ i 1))))))))) 

Two-argument string<? may be defined as follows.

 (define string<?    (lambda (s1 s2)       (let ((n1 (string-length s1)) (n2 (string-length s2)))          (let loop ((i 0))            (and (not (= i n2))                 (or (= i n1)                     (let ((c1 (string-ref s1 i)) (c2 (string-ref s2 i)))                       (or (char<? c1 c2)                       (and (char=? c1 c2)                            (loop (+ i 1))))))))))) 

These definitions may be extended straightforwardly to support three or more arguments. string<=?, string>?, and string>=? may be defined similarly.

 (string=? "mom" "mom")  #t (string<? "mom" "mommy")  #t (string>? "Dad" "Dad")  #f (string=? "Mom and Dad" "mom and dad")  #f (string<? "a" "b" "c")  #t 

(string-ci=? string1 string2 string3 ...)

procedure

(string-ci<? string1 string2 string3 ...)

procedure

(string-ci>? string1 string2 string3 ...)

procedure

(string-ci<=? string1 string2 string3 ...)

procedure

(string-ci>=? string1 string2 string3 ...)

procedure

returns: #t if the relation holds, #f otherwise

These predicates are case-insensitive versions of string=?, string<?, string>?, string<=?, and string>=?. That is, the comparisons are based on the character predicates char-ci=?, char-ci<?, char-ci>?, char-ci<=?, and char-ci>=?.

The ANSI/IEEE standard includes only two-argument versions of these procedures. The more general versions are mentioned in the Revised5 Report.

Two-argument versions of these procedures may be defined in a manner similar to string=? and string<? above.

 (string-ci=? "Mom and Dad" "mom and dad")  #t (string-ci<=? "say what" "Say What!?")  #t (string-ci>? "N" "m" "L" "k")  #t 

(string char ...)

procedure

returns: a string containing the characters char ...

 (string)  "" (string #\a #\b #\c)  "abc" (string #\H #\E #\Y #\!)  "HEY!" 

(make-string n)

procedure

(make-string n char)

procedure

returns: a string of length n

n must be an exact nonnegative integer. If char is supplied, the string is filled with char, otherwise the characters contained in the string are unspecified.

 (make-string 0)  "" (make-string 0 #\x)  "" (make-string 5 #\x)  "xxxxx" 

(string-length string)

procedure

returns: the number of characters in string

The length of a string is always an exact nonnegative integer.

 (string-length "abc")  3 (string-length "")  0 (string-length "hi there")  8 (string-length (make-string 1000000))  1000000 

(string-ref string n)

procedure

returns: the nth character (zero-based) of string

n must be an exact nonnegative integer strictly less than the length of string.

 (string-ref "hi there" 0)  #\h (string-ref "hi there" 5)  #\e 

(string-set! string n char)

procedure

returns: unspecified

n must be an exact nonnegative integer strictly less than the length of string. string-set! changes the nth element of string to char.

 (let ((str "hi three"))    (string-set! str 5 #\e)    (string-set! str 6 #\r)    str)  "hi there" 

(string-copy string)

procedure

returns: a new copy of string

string-copy is equivalent to (lambda (s) (string-append s)). string-copy appears in the Revised5 Report but not in the ANSI/IEEE standard.

 (string-copy "abc")  "abc" (let ((str "abc"))    (eq? str (string-copy str)))  #f 

(string-append string ...)

procedure

returns: a new string formed by concatenating the strings string ...

 (string-append)  "" (string-append "abc" "def")  "abcdef" (string-append "Hey " "you " "there!")  "Hey you there!" 

The following implementation of string-append recurs down the list of strings to compute the total length, then allocates the new string and fills it up as it unwinds the recursion.

 (define string-append    (lambda args       (let f ((ls args) (n 0))         (if (null? ls)             (make-string n)             (let* ((s1 (car ls))                    (m (string-length s1))                    (s2 (f (cdr ls) (+ n m))))                (do ((i 0 (+ i 1)) (j n (+ j 1)))                    ((= i m) s2)                    (string-set! s2 j (string-ref s1 i)))))))) 

(substring string start end)

procedure

returns: a copy of string from start (inclusive) to end (exclusive)

start and end must be exact nonnegative integers; start must be strictly less than the length of string, while end may be less than or equal to the length of string. If end - start, a string of length zero is returned. substring may be defined as follows.

 (define substring    (lambda (s1 m n)       (let ((s2 (make-string (- n m))))          (do ((j 0 (+ j 1)) (i m (+ i 1)))              ((= i n) s2)              (string-set! s2 j (string-ref s1 i)))))) (substring "hi there" 0 1)  "h" (substring "hi there" 3 6)  "the" (substring "hi there" 5 5)  "" (let ((str "hi there"))    (let ((end (string-length str)))       (substring str 0 end)))  "hi there" 

(string-fill! string char)

procedure

returns: unspecified

string-fill! sets every character in string to char. string-fill! appears in the Revised5 Report but not in the ANSI/IEEE standard. It may be defined as follows.

 (define string-fill!       (lambda (s c)          (let ((n (string-length s)))             (do ((i 0 (+ i 1)))                 ((= i n)) (string-set! s i c))))) (let ((str (string-copy "sleepy")))    (string-fill! str #\Z)    str)  "ZZZZZZ" 

(string->list string)

procedure

returns: a list of the characters in string

string->list allows a string to be converted into a list, so that Scheme's list- processing operations may be applied to the processing of strings. string->list appears in the Revised5 Report but not in the ANSI/IEEE standard. It may be defined as follows.

 (define string->list    (lambda (s)       (do ((i (- (string-length s) 1) (- i 1))            (ls '() (cons (string-ref s i) ls)))           ((< i 0) ls)))) (string->list "")  () (string->list "abc")  (#\a #\b #\c) (apply char<? (string->list "abc"))  #t (map char-upcase (string->list "abc"))  (#\A #\B #\C) 

(list->string list)

procedure

returns: a string of the characters in list

list must consist entirely of characters.

list->string is the functional inverse of string->list. A program might use both procedures together, first converting a string into a list, then operating on this list to produce a new list, and finally converting the new list back into a string.

list->string appears in the Revised5 Report but not in the ANSI/IEEE standard. It may be defined as follows.

 (define list->string    (lambda (ls)       (let ((s (make-string (length ls))))          (do ((ls ls (cdr ls)) (i 0 (+ i 1)))              ((null? ls) s)              (string-set! s i (car ls)))))) (list->string '())  "" (list->string '(#\a #\b #\c))  "abc" (list->string    (map char-upcase         (string->list "abc")))  "ABC" 




The Scheme Programming Language
The Scheme Programming Language
ISBN: 026251298X
EAN: 2147483647
Year: 2003
Pages: 98

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net