Finding the Length and Contents of a Text Object

There are two predicates for determining the length of a text object:

string_size(+Text, -Length)

string_length(+Text, -Length)
Length is unified with the number of characters in the name of Text, which must be an atom.

These two predicates are identical except that string_length/2 will report an error if its first argument is not a text object.

There are versions of Quintus Prolog on stock hardware that support Kanji. Those versions currently represent Kanji by pairs of characters. Beware of this difference. This is likely to change.

There are two predicates for extracting a character from a text object:

string_char(?Index, +Text, ?Char)
unifies Char with the character code of the character at position Index (counting from 1) in Text. Being a selector predicate, its arguments follow the convention of being in the same order as those of arg/3; see the description of library(args), lib-tma-arg. Text must be instantiated to a text object. Index, if instantiated, must be an integer. If Index is less than one or greater than the length of Text, string_char/3 fails quietly. If Index is a variable, string_char/3 will enumerate suitable values for Index and Char.
nth_char(?Offset, +Text, ?Char)
is the same as string_char/3 except that Offset counts from 0 rather than from 1. This predicate was added in this release to simplify conversion from another dialect, which is why it is inconsistent with Prolog conventions. We recommend that you use string_char/3 in new programs instead.
     | ?- string_size(fred, X).
     X = 4
     | ?- string_size(47, X).
     | ?- string_length(fred, X).
     X = 4
     | ?- string_length(47, X).
     ! Type error in argument 1 of string_length/2
     ! symbol expected, but 47 found
     ! goal:  string_length(47,_43)
     | ?- X is " ".
     X = 32
     | ?- string_char(3, 'an example', X).
     X = 32
     | ?- nth_char(2, 'an example', X).
     X = 32
     | ?- string_char(I, 'an example', 0'a).
     I = 1 ;
     I = 6 ;
     | ?- nth_char(I, 'an example', 0'a).
     I = 0 ;
     I = 5 ;

We shall see in the next section that nth_char/3 could have been defined by

     nth_char(Offset, Text, Char) :-
             subchars(Text, [Char], Offset, 1, _).

If you wanted a predicate like nth_char/3 but that counted from the right-hand end of the text instead of the left-hand end, you could define

     nth_char_from_right(Offset, Text, Char) :-
             /* this is not in library(strings) */
             subchars(Text, [Char], _, 1, Offset).