Difference between revisions of "Zbex input and output"

From CCARH Wiki
Jump to navigation Jump to search
(added chapter navigator at bottom of page)
(added chapter navigator at top of page)
 
Line 1: Line 1:
 +
{{ZbexChap
 +
  | before =  [[Zbex run and stop statements|The run and stop statements]]
 +
  | after =[[Zbex comments|Comments]]
 +
}}
 +
<center>
 +
__TOC__
 +
</center>
 +
 
After mastering [[Zbex_variable_declaration_statements|declaration]] and [[Zbex_assignment_statements|assignement]] statements, the most important Zbex instructions to learn are the input and output instructions.   
 
After mastering [[Zbex_variable_declaration_statements|declaration]] and [[Zbex_assignment_statements|assignement]] statements, the most important Zbex instructions to learn are the input and output instructions.   
  

Latest revision as of 06:11, 15 October 2010

Previous chapter
The run and stop statements
Zbex
Manual
Next Chapter
Comments

After mastering declaration and assignement statements, the most important Zbex instructions to learn are the input and output instructions.

getc: get data from the next line entered from the screen.

getc may stand alone as an instruction, or it may take variable arguments. If it stands alone, the program will stop running until Enter is pressed. If it has arguments (variables), Zbex will attempt to assign values to the variables using the contents of the next entered line. Examples:

         int a,b 
         str temp.10 
         real x 
   
         getc a x b     (entered line = "10   2.0   15") 

In this case, a will be assigned the value 10, x the value 2.0, and b the value 15.

        getc temp a b  (entered line = "1 2 3 4 5 6 7 8 9") 

In this case, temp will be given the value 1 2 3 4 5 (i.e., the first 10 bytes of the line, a will be assigned the value 6, and b the value 7.

You may reset the point at which Zbex processes a line by using the .t<number> format command. For example, .t1 will reset the process pointer to column one of the input line. Example:

        getc temp .t1 a b   (entered line = "1 2 3 4 5 6 7 8 9") 

In this case, temp will be given the value 1 2 3 4 5 (i.e., the first 10 bytes of the line, a will be assigned the value 1, and b the value 2.

If you respond to a getc by entering two exclaimation points (!!) at the begining of a line, your Zbex program will terminate. This is an important fact to remember, since there are only two ways to stop an Zbex program once it has been started (the other is with Ctrl+Break).

putc: put data to screen at the point where the cursor is.

putc may stand alone as an instruction, or it contain an output string. If the output string has variable arguments, they must be preceded immediately the ~ character and followed immediately by a blank. If the output string ends with three dots (...), no carriage return is given (the cursor stays on the same line); otherwise the cursor is moved to the next line after writing the output string to the screen. Examples:

         int a,b 
         str temp.10 
         real x 
   
         a = 10 
         temp = "Hello" 
         putc temp                 (writes temp to the screen) 
         putc ~temp                (writes Hello to the screen) 
         putc a                    (writes a to the screen) 
         putc ~a                   (writes 10 to the screen) 
    
         putc Hello ...  
         putc there.               (writes Hello there to the screen) 

There are several format commands that can be used to control how things are written to the screen. All format commands start with a dot (.) and end with a blank. Format commands may be combined. Examples:

.t20 move cursor to column 20
.t(a) move cursor to column <a> where a is declared as an integer variable and has some value.
.w6 right justify integer and real variables in a space with 6 columns
.x display integers in hexadecimal format
.e4 display real numbers in floating point notation with 4 digits to the right of the decimal point
.f2 display real numbers in fixed point notation with 2 digits to the right of the decimal point
.c1 precede integers with a dollar sign ($).
.c(a) precede integers with a <depends on a> sign.
.d2 display integers as if they had two digits to the right of a decimal point
           a = 120 
           putc .c1d2 ~a    (line out = $1.20) 
           b = 4 
           putc .c(b)d2 ~a  (line out = DM1.20) 

There is also an easy way to put out any byte value from 0 to 255 using the .b command. This command follows the same rules as the format commands; i.e., it starts with .b, followed by an literal integer or an integer variable in parentheses, followed by a blank. Example:

        putc .b27 A...  

This statement puts out the two byte sequence <esc>A, which happens to be the command for moving the cursor up one line (for a list of all escape sequences, see the section on controlling the (text) display with putc).

putp: put data to the printer port LPT1.

putp works the same way as putc, except that the output is directed to the printer port LPT1 (to your printer, if it is on).


At this point, you should try experimenting with writing Zbex programs. You know how to enter numbers and strings into the computer, how to combine them, and how to print them out on the screen. Remember that the last instruction in an Zbex program must be "run".

Opening files

When you have mastered the getc and putc commands, it is time to learn how to get records from a file and how to put records into a file. To operate on a file, you must first open it. A file can be opened for seven different types of operations:

1 open file for use by getf (get ASCII records sequentually from the file)
2 open file for use by putf (put ASCII records sequentually to a file. Write over any previous contents)
3 open file for use by putf (append ASCII records onto an existing file; no contents are over written)
4 open file for random read only (for use with files with read permission but no write permission)
5 open file for use by random read and write (blocks of arbitrary size)
6 open file for use by write (create new file)
7 open file for use by write (append blocks of arbitrary size)


When you open a file, you must give it a tag. The tag is a number from 1 to 9. You may have up to nine files opened at one time. Any operation (getf, putf, read, write, or close) on an opened file must refer to that file by its tag. The open instruction must supply three pieces of information: (1) the tag for the file you are opening (integer from 1 to 9), (2) the type of operation you want to perform on the file (integer 1,2,3,4,5,6 or 7), (3) the name of the file you want to open. Examples:

        open [1,2] "outfile" 

This will open a file in the current directory. The name will be outfile. The file will be given the tag of 1. The file may exist already, or it may be new. The file is opened for new output, specifically putting records sequentially to the file.

        open [6,4] "bigfile" 

This will open a file called "bigfile" in the current directory. The file must already exist and must have read permission. The file will be given the tag of 6. The file is opened for reading ONLY at random (arbitrary) points in the file. The size of the blocks read is determined at run time.

        open [3,5] "bigfile" 

This will open a file called "bigfile" in the current directory. The file must already exist and must have BOTH read and write permissions. The file will be given the tag of 3. The file is opened for reading and/or writing at random (arbitrary) points in the file. The size of the blocks read or written is determined at run time.

        str filename.80 
   
        filename = "infile" 
        open [5,1] filename 

This will open a file called "infile" in the current directory. The file must already exist. The file will be given the tag of 5. The file is opened for getting ASCII records sequentially from the top of the file.

It sometimes happens that the open command fails. This can occur for a variety of reasons. The file might not exist (for reading); permission might be denied (for reading and writing); permission to create a new file (for writing) might be denied; etc. When this happens, the default behavior is for Zbex to prompt the user for a new (different) file name. This will suspend the operation program until a new name is supplied. Sometimes, however, the user does not welcome this interruption; if the file or directory can't be opened, the user wants the program to ignor the open request and move on. This will happen if bit 12 of the zoperation flag is set = 1. (see Section 18.3 on how to do this using the setflag instruction). In this case, how does the user's program know that open has failed, and why? Answer, Zbex sets the special variable err to one of the following values:

0 open was successful
1 cannot expand to full file name
2 file already open somewhere else
3 cannot open the file at all
4 not a file or a directory
5 unable to read directory
6 read access on file is denied
7 cannot open file for writing
3 cannot open the file at all
8 writing allowed only on regular files
9 read/write access on file is denied
10 write access on file is denied
11 cannot create new file

Program control moves on to the next Zbex instruction, which almost certainly would be to test the value of err. (See Section 17.3 for more on the err special variable.)

When you are finished with a file, you should close it. Closing a file frees up the tag for further use. Example:

        close [5] 

This will close the file whose tag is 5.

The instructions for getting and putting ASCII records sequentially to a file work the same way as those for getting and putting lines to the screen. The only extra item of information required is the file tag. Examples:

getf: get data from the next record in a file.

getf may stand alone as an instruction, or it may take variable arguments. If it stands alone, the program will get the next record in a file, but the contents of the record will be ignored. If getf has arguments (variables), Zbex will attempt to assign values to the variables using the contents of the record. Examples:

         int a,b 
         str temp.10 
         real x 
   
         open [5,1] "<name>" 
   
         getf [5] a x b   (if next record = "10   2.0   15") 

a will be assigned the value 10, x the value 2.0, and b the value 15

        getf [5] temp    (if next record = "ABCDEFGHIJKLM") 

temp will be given the value ABCDEFGHIJ, (i.e., the first 10 bytes of the record. The rest of the record will be ignored.

getf retrieves records sequentially from a file. But what happens when there are no more records to retrieve? In Zbex, trying to retrieve beyond the last record will cause control to jump to the label eofx, where "x" is the tag (digit from 1 to 9) given to the file when it was opened. If the label is not present in the program, the program will terminate when it comes to the end of the file. In the example above, [5] was the tag assigned to the file when it was opened, and, after getting the last record, control will jump to eof5: if it exists.

putf

putf = assemble the data in the output string into a record and append it to the output file referenced by the tag.

putf may stand alone as an instruction, or it contain an output string. If the output string has variable arguments, they must be preceded immediately the ~ character and followed immediately by a blank. If the output string ends with three dots (...), the record is assembled but not put to the file (yet). The data from the next putf statement is append to this record. Examples:

         int a,b 
         str temp.10 
         real x 
   
         a = 10 
         temp = "Hello" 
         putf [1] temp     (adds a record containing the string "temp" 
                              to file [1]) 
         putf [1] ~temp    (adds a record containing the string "Hello" 
                              to file [1]) 
         putf [1] a        (adds a record containing the string "a" 
                              to file [1]) 
         putf [1] ~a       (adds a record containing the string "10" 
                              to file [1]) 
         putf [1] Hello ...  
         putf [1] there.   (adds a record containing the string 
                              "Hello there." to file [1]) 

The format commands described for putc also work for putf.


At this point, you should experiment with opening files for putting and getting records. Try getting records first. One possible program you might try is this:

     str file.80, rec.120 
  
     putc File name?  
     getc file 
   
     open [1,1] file 
   
     getf [1] rec 
     putc ~rec 
     close [1] 
     run 

Can you guess what this program does?


The read and write commands allow you to create and access files which are not organized as a sequence of ASCII records. We call these files binary files, because there is no limitation placed on value of the bytes they contain. (ASCII bytes normally have values between 32 and 255).

read: read a block of data from a file into a string

The read command requires three pieces of information: (1) the file tag number, (2) the point in the file where you want to start reading, and (3) the string where you want the read data to be placed. The read starting point (2) may be specified explicitly or may be implied. This gives rise to two formats, (a) and (b), for the read instruction:


(a) read [<num>] string <num> is file tag number, start is implied
(b) read [<num>,<start>] string <start> is starting point

Note: <start> = 1 indicates start reading at the first byte

The number of bytes read is determined by the run-time length of the destination string. If the run-time length is zero, no bytes are read.

Each file that is open for reading has a special variable called the read pointer. When the file is first opened, Zbex automatically sets this (read pointer) variable to 1. (i.e., pointing at the first byte in the file). If a read instruction is encountered in the (b) format above, the read pointer is set to the value of <start> before the read takes place. And after any read takes place, the read pointer is set to the byte (in the file) following the last byte read. Thus it is possible to used both formats of the read instruction for a file open for reading. In practice, however, format (a) is best suited for sequential reading applications and format (b) is best suited for random reading.

Can you guess what the following program would do?

     str file.80, rec.120 
  
     putc File name?  
     getc file 
   
     open [1,5] file 
   
     rec = pad(10)            
     read [1,1] rec 
     putc ~rec 
     close [1] 
     run 

Answer: It will open and try to read the first 10 bytes of the file you specify. The result is sent to the screen as an ASCII string.

write: write a block of data to a file.

If a file is open for both read and write (type 5 access), the write instruction requires three pieces of information: (1) the file tag number, (2) the point in the file where you want to start writing (1 = first byte), and (3) the string containing the data you want to write. If a file is open for write only (type 6 or type 7 access), then the write instruction requires only two pieces of information: (1) the file tag number, and (2) the string containing the data you want to write. In this case, the data will be appended to whatever has already been written to the file. Example:

     str file.80, rec.120 
   
     putc File name?  
     getc file 
    
     open [1,6] file 
    
     rec = "This is a data string.  " 
     write [1] rec 
     putc ~rec 
     close [1] 
     run 

This program tries to open the file you specify for writing. If the file does not already exist, it is created; if it does exist, it is over-written. If successful, the file will consist of 26 bytes: the 24 byte string above, and the line termination sequence CR/LF (ASCII-10, ASCII-11)["not right numbers"]


Previous chapter
The run and stop statements
Zbex
Manual
Next Chapter
Comments