Text Input and Output
You learned earlier how to do single character I/O. This section concentrates on
using strings of characters.
A D V E R T I S E M E N T
You can embed a text string in your program using
S". Note that you must follow the S" by one space. The text string is terminated
by an ending " .Enter:
: TEST S" Hello world!" ;
TEST .S
Note that TEST leaves two numbers on the stack. The first number is the address
of the first character. The second number is the number of characters in the
string. You can print the characters of the string as follows.
TEST DROP \ get rid of number of characters
DUP C@ EMIT \ prints first character, 'H'
CHAR+ DUP C@ EMIT \ prints second character, 'e'
\ and so on
CHAR+ advances the address to the next character. You can print the entire
string using TYPE.
TEST TYPE
TEST 2/ TYPE \ print half of string
It would be nice if we could simply use a single address to describe a string
and not have to pass the number of characters around. 'C' does this by putting a
zero at the end of the string to show when it ends. Forth has a different
solution. A text string in Forth consists of a character count in the first
byte, followed immediately by the characters themselves. This type of character
string can be created using the Forth word C" , pronounced 'c quote'. Enter:
: T2 C" Greetings Fred" ;
T2 .
The number that was printed was the address of the start of the string. It
should be a byte that contains the number of characters. Now enter:
You should see a 14 printed. Remember that C@ fetches one character/byte at the
address on the stack. You can convert a counted Forth string to an address and
count using COUNT.
The word COUNT extracts the number of characters and their starting
address. COUNT will only work with strings of less than 256 characters, since
255 is the largest number that can be stored in the count byte. TYPE will,
however, work with longer strings since the length is on the stack. Their stack
diagrams follow:
CHAR+ ( address -- address' , add the size of one character )
COUNT ( $addr -- addr #bytes , extract string information )
TYPE ( addr #bytes -- , output characters at addr )
The $addr is the address of a count byte. The dollar sign is often used to
mark words that relate to strings.
You can easily input a string using the word ACCEPT. (You may want to
put these upcoming examples in a file since they are very handy.) The word
ACCEPT receives characters from the keyboard and places them at any
specified address. ACCEPT takes input characters until a maximum is
reached or an end of line character is entered. ACCEPT returns the number
of characters entered. You can write a word for entering text. Enter:
: INPUT$ ( -- $addr )
PAD 1+ ( leave room for byte count )
127 ACCEPT ( recieve a maximum of 127 chars )
PAD C! ( set byte count )
PAD ( return address of string )
;
Enter a string which should then be echoed. You could use this in a program that
writes form letters.
: FORM.LETTER ( -- )
." Enter customer's name." CR
INPUT$
CR ." Dear " DUP COUNT TYPE CR
." Your cup that says " COUNT TYPE
." is in the mail!" CR
;
ACCEPT ( addr maxbytes -- numbytes , input text, save at address )
You can use your word INPUT$ to write a word that will read a number from the
keyboard. Enter:
: INPUT# ( -- N true | false )
INPUT$ ( get string )
NUMBER? ( convert to a string if valid )
IF DROP TRUE ( get rid of high cell )
ELSE FALSE
THEN
;
This word will return a single-precision number and a TRUE, or it will just
return FALSE. The word NUMBER? returns a double precision number if the
input string contains a valid number. Double precision numbers are 64-bit so we
DROP the top 32 bits to get a single-precision 32 bit number.
|