home *** CD-ROM | disk | FTP | other *** search
- ******************************************************************************
- *
- * LINCOUNT.PRG
- *
- * Written by Cai Campbell
- * Compuserve I.D. 72622, 1771
- *
- * LinCount is a great way to find out how many lines are in an ASCII text
- * file. It does this by searching for carriage return/linefeed combinations.
- * The number of lines is equivalent to the number of CR/LF's found.
- *
- * I developed LinCount because I do a lot of data conversion via Clipper. I
- * import delimited or SDF ASCII files into xBASE format for manipulation,
- * then spit them out in whatever format is needed. Before I import an ASCII
- * text file into xBASE, I like to know how many records I am dealing with.
- * File size is usually not a good measure, especially with varying length
- * records found in delimited files.
- *
- * I have played around with different methods and parameters and the
- * resulting code here is very efficient. In testing, I was able to scan
- * a 1.5 meg file in three seconds and a 6 meg file in sixteen seconds (on a
- * 486 DX2 66mhz machine.) Not bad for Clipper, I'd say!
- *
- * Hope you find this program useful!
- *
-
- #include "FileIO.ch"
- #define CRLF CHR(13) + CHR(10)
-
- #define F_BLOCK 2048 // Buffer size. Seems to work optimally between 512
- // and 4096 bytes. A larger buffer seems to bog the
- // process down (which is the exact opposite of what
- // I had expected.) This seems to point to an
- // inefficiancy in Clipper's string-handling abilities.
- // If anyone knows why this is, I'd be keen on hearing
- // from you!
-
- PROCEDURE Main
-
- PARAMETER cFile // Input parameter - filename.
-
- LOCAL cFlushBuffer := SPACE ( F_BLOCK )
- LOCAL cBuffer := cFlushBuffer
- LOCAL nBytes := F_BLOCK
- LOCAL nPosition := 0, nFoundAt := 1, nNumLines := 0, nHandle
-
- IF cFile == NIL // No file parameter included.
- ? "Usage: LINCOUNT [pathname]filename"; ?
- RETURN
- ELSEIF .NOT. FILE ( cFile )
- ? "Error: file " + cFile + " not found"; ?
- RETURN
- END IF
-
- nHandle := FOPEN ( cFile )
-
- DO WHILE nBytes == F_BLOCK // Continue filling buffer until buffer
- // doesn't fill up completely.
- nBytes := FREAD ( nHandle, @cBuffer, nBytes )
- DO WHILE .NOT. ( ( nFoundAt := AT ( CRLF, SUBSTR ;
- ( cBuffer, nPosition, nBytes ) ) ) == 0 )
- nPosition += nFoundAt + 1 // This loop cycles through the current
- nNumLines += 1 // buffer until it doesn't find any
- END DO // more CR/LF's.
- FSEEK ( nHandle, -1, FS_RELATIVE ) // Back up one byte in case the
- // file pointer stops between a CR
- // and an LF.
- cBuffer := cFlushBuffer // Reset the buffer.
- nPosition := 0 // Reset last found position pointer.
- END DO
-
- FCLOSE ( nHandle )
-
- ? STR ( nNumLines ) + " lines found in " + cFile; ?
-
- RETURN
-