Turbo Pascal Text Adventure Primer cover: BEACON, the adventure the primer builds in Turbo Pascal 2.0, mid-game on the Tatung Einstein
← Back to Modules
module
3

Strings Up Close

Introduction

The Turbo course's S10 showed you strings as boxes of text: give one a value, measure it, cut pieces out. A text adventure leans on strings so heavily that it pays to know exactly what the box looks like inside, and exactly what happens when you reach past its end, because a parser spends its life doing that.

A String In Memory

A string[20] is 21 bytes of memory, always, whether it holds twenty characters or none. The first byte, number 0, holds the length: how many of the other twenty are in use. The characters follow it, from byte 1.

S := 'LANTERN';

byte:  0   1   2   3   4   5   6   7   8 ... 20
      [7] [L] [A] [N] [T] [E] [R] [N] [?] ... [?]

The bytes past the length hold whatever was there before. Turbo never looks at them.

SizeOf(S) tells you how many bytes a variable or a type takes: 21 here. That matters when you have a lot of strings. An array of fifty string[30]s is 1,550 bytes even if every one of them is empty, so choose lengths with care. A record is exactly the sum of its fields: a string[20] and four bytes make 25.

Changing The Length Directly

Ord(S[0]) is the length (S10). You can also set it:

S[0] := Chr(4);

and S is now LANT. Nothing has been erased: the ERN is still in bytes 5 to 7, unseen. Set the length back to 7 and LANTERN reappears.

That makes S[0] the quickest way to shorten a string from the end, one assignment instead of a Delete. It is also a way to make nonsense: set the length past the characters you put there and you will see whatever happened to be in memory. Only ever shorten with it, or lengthen back over characters you know are there.

At The Edges

A parser constantly asks for pieces of strings that may not be there: the next word when there is none, the rest of a line that has ended. Turbo is forgiving about most of it.

Asking forYou get
Copy(S, 5, 10) on LANTERN, more than there iswhat there is: ERN
Copy(S, 9, 3), starting past the endthe empty string
Copy(S, 3, 0), or a negative countthe empty string
Delete(S, 5, 10), more than there iseverything from 5 deleted: LANT
Delete(S, 9, 2), starting past the endnothing deleted
Insert('xx', S, 20), past the end'xx' added on the end
Insert('xyz', T, 3) into a string[8] holding ABCDEFGthe result cut to 8: ABxyzCDE

And Pos('', S) is 0: the empty string is never found.

Two Ways To Stop A Program

Two things are not forgiven.

A position of 0, or over 255, in Copy, Delete or Insert stops the program with Run-time error 11. The commonest way to get there is a position worked out from Pos: when Pos finds nothing it gives 0, and Copy(S, Pos(' ', S), 5) on a string with no space stops the program.

A string that would be longer than 255 stops the program with Run-time error 10, whether it was made with + or Concat. So does putting a string into a Char variable when the string is not exactly one character long, the empty string included.

Each time, Turbo prints the error, Program aborted, finds the place in your program, and waits for ESC to show it to you in the editor.

The Code

program Inside;
type
  Str20 = string[20];
var
  S: Str20;
begin
  S := 'LANTERN';
  Writeln(S, ' ', Length(S), ' ',
          Ord(S[0]));
  Writeln('Bytes: ', SizeOf(S));
  S[0] := Chr(4);
  Writeln(S);
  S[0] := Chr(7);
  Writeln(S);
  Writeln('[', Copy(S, 5, 10), ']');
  Writeln('[', Copy(S, 9, 3), ']');
  Delete(S, 5, 10);
  Writeln(S, ' ', Length(S));
end.

Starting from

Turbo freshly started, Y, a new work file called INSIDE.

What you should see

LANTERN 7 7
Bytes: 21
LANT
LANTERN
[ERN]
[]
LANT 4

Change One Thing

  • Change Str20 = string[20] to string[255]. Which line changes, and to what?
  • Change Copy(S, 9, 3) to Copy(S, 0, 3). What happens, and notice how much of that line was printed before it happened.
  • Change S[0] := Chr(4); to S := S + S + S;. What is printed on the third line, and why is the fourth line still LANTERN?

Exercises

3.1 Write a procedure Trim(var S: Str20) that removes any spaces from the end of S by shortening it with S[0]. Test it on 'LAMP ', printing the string in square brackets with its length before and after.

3.2 Print a word backwards, one character at a time.

3.3 Using SizeOf, print how many bytes one string[30] takes, and how many an array of fifty of them takes.

Worked solutions are in Appendix II.

When It Goes Wrong

SymptomCause
Run-time error 11A position of 0, or over 255, given to Copy, Delete or Insert. Often a Pos that found nothing, used in a sum.
Run-time error 10A string longer than 255, or a string that is not one character long put into a Char.
Strange characters after your textYou set S[0] longer than the characters you had put there.
The end of the text has gone, with no errorThe variable is shorter than the text. Turbo cuts it silently.

Summary

A string[n] is n + 1 bytes: a length byte, then the characters. S[0] := Chr(n) sets the length directly. Copy, Delete and Insert quietly clip whatever runs past the end; a position outside 1 to 255 is Run-time error 11, and a string over 255 characters, or one put into a Char without being exactly one character long, is Run-time error 10.

Next

S4, Reading The Command, Two Ways: getting the player's sentence in.

Get the Newsletter

New guides, disk images and community finds, roughly once a quarter. No spam, we promise, this isn't Tatung's marketing department.
Your subscription could not be saved. Please try again.
Your subscription has been successful.

Newsletter

Subscribe to our newsletter and stay updated.

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.