Slicing strings is just like copying strings. We just don't copy all of it and we don't always start copying at the beginning of a string. We'll show you what we mean:
32 string one \ define string one " Hans Bezemer" one copy \ initialize string one dup count type cr \ duplicate and print it char+ \ move one character forward dup count type cr \ duplicate and print it again char+ \ move one character forward dup count type cr \ duplicate and print it again char+ \ move one character forward count type cr \ print it for the last time
First it will print "Hans Bezemer", then "ans Bezemer", then "ns Bezemer" and finally "s Bezemer". The word 'CHAR+' is functionally equivalent to '1+', but a more portable way to do manipulations on strings. If we want to discard the first name at all we could even write:
32 string one \ define string one " Hans Bezemer" one copy \ initialize string one 5 chars + count type cr \ print sliced string
The five characters we want to skip are the first name (which is four characters) and a space (which adds up to five). There is no special word for slicing strings. There is a smarter way to handle strings in 4tH, which we will discuss later on. But if you desperately need slicing you might want to use a word like this. It works just like 'CMOVE' with an extra parameter:
: slice$ over over \ copy the dest and #chars >r >r >r >r \ store on the return stack chars + \ make address to the source r> r> \ restore dest and #chars cmove \ copy the string 0 \ throw NULL char. on stack r> r> \ restore dest and #chars chars + \ make index to slice c! \ terminate string ;
This is another example of "you're not supposed to understand this". You call it with:
source index-to-source destination #chars
The index-to-source starts counting at zero. So this will copy the first name to string "two" and print it:
: slice$ over over \ copy the dest and #chars >r >r >r >r \ store on the return stack chars + \ make address to the source r> r> \ restore dest and #chars cmove \ copy the string 0 \ throw NULL char. on stack r> r> \ restore dest and #chars chars + \ make index to slice c! \ terminate string ; 32 string one \ declare string one 32 string two \ declare string two " Hans Bezemer" one copy \ initialize string one 0 two 4 slice$ \ slice the first name two count type cr \ print string two
This will slice the last name off and store it in string "two":
: slice$ over over \ copy the dest and #chars >r >r >r >r \ store on the return stack chars + \ make address to the source r> r> \ restore dest and #chars cmove \ copy the string 0 \ throw NULL char. on stack r> r> \ restore dest and #chars chars + \ make index to slice c! \ terminate string ; 32 string one \ declare string one 32 string two \ declare string two " Hans Bezemer" one copy \ initialize string one 5 two 7 slice$ \ slice the first name two count type cr \ print string two
Since the last name is seven characters long and starts at position five (start counting with zero!). Although this is very "Basic" way to slice strings, we can do this kind of string processing the 4tH way. It will probably require less stack manipulations.