LOOP UNTIL condition
To create a conditional loop.See Also: FOR...NEXT
There are several ways to make statements loop in QBasic, and two of them are the DO...LOOP and WHILE...WEND statements. The only significant difference between these two looping structures is that WHILE...WEND checks the condition before running the loop, and DO...LOOP checks the condition only after the loop has executed once:
WHILE x < 3
x = x + 1
x = x - 1
LOOP UNTIL x <= 0
In the example, the WHILE...WEND structure would run only as long as x was less than 3. Since x was being incremented inside the loop, the loop does not repeat again after the "x = x + 1" assignment that set x to 3. Then in the DO...LOOP structure, the variable "x" is decremented each cycle. In the first cycle, the value of x is changed from 3 to 2 and printed. Since x = 2 which is not less <= 0, the program will repeat the loop.
Notice that the form of the condition is inverted for these two loops. In the WHILE...WEND statement, the loop executes as long as the condition is true. In the DO....LOOP statement, the loop executes as long as the condition is false, exiting only when the condition is true. The WHILE...WEND condition could be said to be keeping the loop going, and the DO...LOOP condition could be said to be trying to find an exit.
At some time you may need to use a WHILE of DO loop, but the condition is inverse to what you want. Simply use the NOT keyword to adjust the condition. For example, if you want a WHILE...WEND to execute until a condition is met put a "NOT" in front of it:
WHILE NOT (a = 5)
a = a + 1
FOR variable = range1 TO range2 [STEP interval]Purpose:
To execute statements multiple times, causing the variable used to cycle through values as specified.See Also: DO...LOOP / WHILE...WEND
One of the most time saving commands (both programming time and processing time) is the FOR...NEXT command. A single FOR...NEXT loop executes a group of statements multiple times as specified. For each loop, the variable used holds the value of the state of the loop:FOR T = 1 to 5 PRINT T NEXT T
Output:1 2 3 4 5
The variable `T' was put into a loop, increasing by 1 (default) for each time the cycle was run. Any commands inside the FOR...NEXT loop that depend on the variable `T' are affected. In the above example when the PRINT command displayed the value of `T' it had incremented by one for each time around the loop.
The loop does not always have to start at 1. The increment value does not have to be 1 either, nor does it have to be positive or even an integer. The following example shows the different abilities of FOR...NEXT loops:' Print the numbers 5,6,7,8,9,and 10 FOR t = 5 to 10 PRINT t NEXT t ' Print the numbers 5,7,and 9 FOR t = 5 to 10 STEP 2 PRINT t NEXT t ' Print the numbers 7,6,5,4,and 3 FOR t = 7 to 4 STEP -1 PRINT t NEXT t ' Print the numbers 3.3, 3.5, and 3.7 FOR t = 3.3 TO 3.7 STEP .2 PRINT t NEXT t ' Add a value to x for each loop FOR t = 1 to 10 x = x + 5 PRINT x NEXT t ' Output is 0,5,10,15,20...
The value of the variable does not have to be used by the statement within the loop, as demonstrated by the last FOR...NEXT loop example. Loops may be placed within each other, as long as different variables are used. This is called "nesting".FOR y = 1 to 10 FOR x = 1 to 10 LOCATE y, x PRINT "." NEXT x NEXT y
The loops must be resolved with NEXT in the reverse order that they are used in. Remember that FOR...NEXT loops are statements as any other, so more commands than just another loop may exist in a FOR...NEXT nested loop situation:FOR y = 1 to 9 LOCATE y, 1 PRINT y FOR x = 1 to 9 LOCATE y, x + 4 PRINT "." NEXT x NEXT y
Many loops can be nested within eachother in any combinations, as long as a loop is terminated before the loop in which it is nested terminates. In other words:' Proper positioning FOR x = 1 to 10 <--\ FOR y = 1 to 5 <--\ | . | | . | | NEXT y <--/ | NEXT x <--/ ' Improper positioning FOR x = 1 to 10 <--\ FOR y = 1 to 5 <--\ | . | | . | | NEXT x | <--/ NEXT y <--/
For a very interesting reason about which I'm not going to tell you here, you must have the condition in parentheses if you wish to have "NOT" in front of it.
GOTO linenumber | linelabelPurpose:
Manual branching from one location fo a program to another.
The GOTO statement has been the maker and breaker of programs since the beginning of programming. Used incorrectly, they make a mess of code and tourbleshooting becomes almost impossible. Used properly (meaning, very seldom in QBasic) and they save lots of brainpower at figuring a better program flow scheme.
More simply put, GOTO makes QBasic run lines of commands in an order different from how they are written. GOTO requires that a line label be implemented at some point in the code as a destination. This line label MUST be within the same subroutine, funtion, or main program. GOTO cannot branch from a subroutine to the main program or another subroutine or function, and vice-versa. In QBasic, the line label can be either a number, a word, or a combination of the two as long as it is unique within the program.
PRINT "Line of text #1"A label must be followed by a colon (:) in order for it to function as a label. Notice also that the labels "10" and "abcd" only appeared as labels once in the program. This does not mean that only one GOTO 10 statement may exist in the program. GOTO 10 may be used as many times as needed.
PRINT "This line gets skipped"
PRINT "Line of text #2"
PRINT "QBasic will not execute this line either"
PRINT "Line of text #3"
Line of text #1
Line of text #2
Line of text #3
ON ERROR GOTO Syntax:
ON ERROR GOTO linelabelPurpose:
RESUME linelabel | NEXT
ON ERROR GOTO is used to trap error events when the occur. RESUME tells where to resume the program flow once the error is handled. ERROR manually causes a simulation of a specific error, used mainly for troublshooting the error trapping code.See Also: ERR
In most simple QBasic programs, there is no need for error handling code as long as potential errors are foreseen and protected against. Some examples of avoidable errors are: LOCATE x, y when x or y are 0 or too big, divisions by zero, and input past end of file. The the values of x and y can be checked before being used in LOCATE, the divisor can also be checked for the same thing, and the EOF() function signals that there is no more data in a file.
Some of the notoriously unpredictable errors are related to file input and output. For example, file not found, disk full, file already exists, and disk-media error are all errors that are unavoidablly caused by human error or hardware failure. To do a complete job as a programmer, any program that risks these errors must have error handling code.
To initiate error handling, the ON ERROR GOTO statement indicated where the program flow will go if there is any error during run-time of the program.
ON ERROR GOTO Handle
When there is an error, program flow will be sent to the line lable "Handle", which must be located within the main program body (not a subroutine or function). The error handling code will the decide what will be done about the error. The response may need to be different for the different errors that happen. The ERR variable contains a code for the error last error that occurred. This variable can be used to run conditionals for the error handler:
SELECT CASE ERR
CASE 53: PRINT "That file does not exist"
CASE 71: PRINT "Disk is not ready"
CASE 76: PRINT "That path does not exist"
CASE ELSE: PRINT "Unrecoverable error. Ending program."
In the above error handler, certain error codes are recognized, appropriate error messages are given for them, and the program continues. If the error code is not one that is recognized by the error handler, the "unrecoverable error" message is printed and the program ends.
A problem arises when the program flow is returned to the point of the error. When the program is trying to open a file and the File Not Found error happens, there is nothing that will signal to the lines after the error that there is something wrong. An easy way to deal with this is to have a flag set that can be checked after a potential error causing command:
'In the handler have the line...
errorflag = 1
'In the normal code...
OPEN filename$ for INPUT AS #1
IF errorflag = 1 then
errorflag = 0
INPUT #1, variable
In the above code, the reading from the opened file only continues if the errorflag variable is not set. In the case that it is set, the code resets it to zero for its next use. In the above code, the errorflag variable must be a COMMON SHARED variable.
Sometimes you may need to cause an error manually in order to check your error code, or in some cases, just cause a fake error event to happen. The ERROR statement does just that.
This causes a "File Not Found" error. If there is event trapping, ERR will be equal to 53 and the code will execute. If there is no error trapping, the QBasic program will stop and the QBasic editor will display the error dialog box with "File not found".
There is one "error" code in QBasic that does not produce and actual error, but merely trips the error trapper. The error code is 97. You could simply use another error code, such as 53, for your manual interrupt, but then what if there is a real error 53? ERROR 97 is an error code that nothing in your program will cause, except for the ERROR statement. The use for ERROR 97 is good for cases where you want some code to execute from no matter where you are in the program. It is mmore powerful than a subroutine, because you can have the progrma return to the place where ERROR 97 ocurred with RESUME NEXT, OR you could have it proceed to set linelable with RESUME linelable. The application for this can be very handly, since you can then trigger a manual jump to the main program code without having to care about exiting through multiple levels of subroutines.
QBasic showing a syntax error.
Now QBasic recognizes the command. In addition, it changed the word "input" to all capital letters because INPUT, like CLS, is a QBasic keyword. However, just because QBasic can now make sense of the line doesn't mean the line is correct. It only means that the line follows QBasic's syntax rules. You still have two misspelled words: "Whatis" and "yourr."
QBasic's text editor enables you to correct typing mistakes easily. First, use the arrow keys to position the flashing text cursor under the space between the words "yourr" and "name." Now press the Backspace key. Presto! The extra letter vanishes, and the rest of the line moves to the left to fill in the space you deleted.
You still have a mistake in the line, though. There should be a space between the words "What" and "is." Luckily, you can add characters to a line as easily as you can delete them. Use the arrow keys to position the blinking text cursor under the "i" in the word "Whatis" and then press the spacebar. When you do, a space character appears at the text cursor's position, and the rest of the line moves to the right.
Finish typing the program by adding the following lines. Remember to type them exactly as they're shown. To indent the line that starts with the word PRINT, start by typing two spaces.
FOR X = 1 TO 200
PRINT Name$; " ";
Error Codes and Messages
When error handling becomes important in your programs, you need to know which error codes are generated for each error. When an error occurrs and the ON ERROR event is trapped, the ERR variable contains the error code. Following is the list of what each error code means.
||NEXT without FOR|
||RETURN without GOSUB|
||Out of DATA|
||Illegal function call|
||Out of memory|
||Label not defined|
||Subscript out of range|
||Division by zero|
||Illegal in direct mode|
||Out of string space|
||String formula too complex|
||Function not defined|
||RESUME without error|
||FOR without NEXT|
||Out of paper|
||WHILE without WEND|
||WEND without WHILE|
||Subprogram not defined|
||Array not defined|
||CASE ELSE expected|
||Bad file name or number|
||File not found|
||Bad file mode|
||File already open|
||FIELD statment active|
||Device I/O error|
||File already exists|
||Bad record length|
||Input past end of file|
||Bad record number|
||Bad file name|
||Too many files|
||Disk not ready|
||Advanced feature unavailable|
||Rename across disks|
||Path/File access error|
||Path not found|
||(no error message)|