"Input Past End of File" with INPUT #; Use LINE INPUT # (82001)



The information in this article applies to:

  • Microsoft QuickBASIC 4.0
  • Microsoft QuickBASIC 4.0b
  • Microsoft QuickBASIC 4.5
  • Microsoft Basic Professional Development System (PDS) for MS-DOS and MS OS/2 7.0
  • Microsoft Basic Professional Development System (PDS) for MS-DOS and MS OS/2 7.1
  • Microsoft QuickBASIC Compiler for the Apple Macintosh 1.0
  • Microsoft QuickBASIC Compiler for the Apple Macintosh 1.0a
  • Microsoft QuickBASIC Compiler for the Apple Macintosh 1.0b
  • Microsoft Visual Basic Standard Edition for Windows 1.0

This article was previously published under Q82001

SUMMARY

When reading a sequential file, the INPUT # statement may produce the error
Input past end of file
even if the function EOF returns False (0) immediately before the INPUT #. This run-time error occurs when the INPUT # statement attempts to read more than one value, and not enough values remain in the file. The EOF function works properly with sequential text files in all versions of Microsoft Basic products.

To avoid this run-time error, use the LINE INPUT statement to read one line at a time and parse values out of the input string.

MORE INFORMATION

The error "Input past end of file" (error code 62) can occur when you use the INPUT # statement in a loop to iteratively read a fixed number of values from each line of a sequential (text) file, and one of the lines in the file has the wrong number of values. This happens because INPUT # reads across line boundaries. For example, when there are too few values on a line, INPUT # continues reading values from the next line. This leaves too few values on the next line for the following INPUT # iterations. When reading the last line in the file, the error occurs.

Example Program

The program below demonstrates how INPUT # can produce "Input past end of file" due to a missing data value, and demonstrates how to use LINE INPUT # to read each line from the file and then retrieve the values from the input line.
DIM seenError%  ' tells if error "Input past end of file" occurred
CLS
q$ = CHR$(34)   ' the double-quote character (")

' Create a sequential data file with a missing value.
' The data also contains other minor problems that parseNumber
' and parseString handle better than INPUT #.
OPEN "data.txt" FOR OUTPUT AS 1
WRITE #1, 1, "two", 3    ' good data
WRITE #1, 2, "eleven"    ' missing value causes Input past end of file
PRINT #1, 3; ",,"; 10.25    ' unquoted null string
PRINT #1, 4; "eight,"; 9.5  ' good data
PRINT #1, 5; q$ + "one,"; 9 ' unmatched quote
CLOSE 1

' Read the data back from the file using INPUT #. This results in
' the error "Input past end of data" due to the missing value.
OPEN "data.txt" FOR INPUT AS 1
ON ERROR GOTO errorHandler
DO UNTIL EOF(1)
    INPUT #1, a%, b$, c#
    IF seenError% THEN
        PRINT "error"
    ELSE
        PRINT a%; "'"; b$; "'"; c#
    END IF
LOOP
ON ERROR GOTO 0
CLOSE 1

PRINT "=========="

' Read the data again using LINE INPUT #.
' The parseNumber and parseString functions print several error
' messages due to the missing value (parseNumber: null string) and
' other minor problems (unmatched ", unquoted null string).
OPEN "data.txt" FOR INPUT AS 1
DO UNTIL EOF(1)
    LINE INPUT #1, buf$
    a% = parseNumber(buf$)
    b$ = parseString(buf$)
    c# = parseNumber(buf$)
    PRINT a%; "'"; b$; "'"; c#
LOOP
CLOSE 1

END

errorHandler:
    IF ERR = 62 THEN
        ' input past end of file
        seenError% = -1
    ELSE
        ERROR ERR
    END IF
    RESUME NEXT

' parseNumber
'   Purpose
'     Retrieve and delete a numeric value from the beginning of an
'     input string. The number is terminated by a comma, space, a
'     double quote (string value), or the end of the input string. A
'     terminating comma is deleted. If no numeric value occurs before
'     the terminator, an error message is printed.
'   Parameters
'     buf$  -- the input string, modified by this function
'   Return
'     n!    -- the number retrieved
FUNCTION parseNumber! (buf AS STRING)
    DIM n AS DOUBLE      ' return value
    DIM s AS STRING      ' the value as a string
    DIM quote AS STRING  ' double quote character

    quote = CHR$(34)

    ' skip leading spaces
    DO WHILE LEFT$(buf, 1) = " "
        buf = MID$(buf, 2)
    LOOP

    ' get value into temporary string
    ' terminated by space, comma, or quote
    DO UNTIL buf = "" OR INSTR(" ," + quote, LEFT$(buf, 1))
        s = s + LEFT$(buf, 1)
        buf = MID$(buf, 2)
    LOOP
    IF s = "" THEN
        PRINT "parseNumber: null string"
        n = 0
    ELSE
        n = VAL(s)
    END IF

    ' skip trailing spaces and comma
    DO WHILE LEFT$(buf, 1) = " "
        buf = MID$(buf, 2)
    LOOP
    IF LEFT$(buf, 1) = "," THEN
        buf = MID$(buf, 2)
    END IF

    parseNumber = n
END FUNCTION

' parseString
'   Purpose
'     Retrieve and delete a string value from the beginning of an
'     input string. If the value begins with a double quote (") then
'     it is terminated by a subsequent double quote, otherwise the
'     string is terminated by a comma or the end of the input string.
'     A terminating comma is deleted. Error messages are printed if
'     the value begins with a double quote but does not end with a
'     double quote, or if an unquoted null string value occurs.
'   Parameters
'     buf$  -- the input string, modified by this function
'   Return
'     s$    -- the string retrieved
FUNCTION parseString$ (buf AS STRING)
    DIM s AS STRING         ' return value
    DIM quote AS STRING     ' double quote character
    DIM terminal AS STRING  ' close quote or comma

    quote = CHR$(34)
    s = ""

    ' skip leading spaces
    DO WHILE LEFT$(buf, 1) = " "
        buf = MID$(buf, 2)
    LOOP

    ' determine if quoted or unquoted
    IF LEFT$(buf, 1) = quote THEN
        terminal = quote
        buf = MID$(buf, 2)
    ELSE
        terminal = ","
    END IF

    ' get value
    DO UNTIL buf = "" OR LEFT$(buf, 1) = terminal
        s = s + LEFT$(buf, 1)
        buf = MID$(buf, 2)
    LOOP

    ' check closing quote
    IF terminal = quote THEN
        IF buf = "" THEN
            PRINT "parseString: unmatched " + quote + " on " + s
        ELSE
            ' skip closing quote
            buf = MID$(buf, 2)
        END IF
    ' unquoted null string not allowed
    ELSEIF s = "" THEN
        PRINT "parseString: unquoted null string"
    END IF

    ' skip trailing spaces and comma
    DO WHILE LEFT$(buf, 1) = " "
        buf = MID$(buf, 2)
    LOOP
    IF LEFT$(buf, 1) = "," THEN
        buf = MID$(buf, 2)
    END IF

    parseString = s
END FUNCTION
				

Modification Type:MinorLast Reviewed:8/16/2005
Keywords:KB82001