home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / VRAC / STATWIN.ZIP / LINCOUNT.PRG < prev    next >
Encoding:
Text File  |  1993-09-02  |  3.1 KB  |  77 lines

  1. ******************************************************************************
  2. *
  3. *   LINCOUNT.PRG
  4. *
  5. *   Written by Cai Campbell
  6. *   Compuserve I.D. 72622, 1771
  7. *
  8. *   LinCount is a great way to find out how many lines are in an ASCII text 
  9. *   file.  It does this by searching for carriage return/linefeed combinations.  
  10. *   The number of lines is equivalent to the number of CR/LF's found.
  11. *
  12. *   I developed LinCount because I do a lot of data conversion via Clipper.  I
  13. *   import delimited or SDF ASCII files into xBASE format for manipulation,
  14. *   then spit them out in whatever format is needed.  Before I import an ASCII
  15. *   text file into xBASE, I like to know how many records I am dealing with.
  16. *   File size is usually not a good measure, especially with varying length
  17. *   records found in delimited files.
  18. *
  19. *   I have played around with different methods and parameters and the
  20. *   resulting code here is very efficient.  In testing, I was able to scan
  21. *   a 1.5 meg file in three seconds and a 6 meg file in sixteen seconds (on a
  22. *   486 DX2 66mhz machine.)  Not bad for Clipper, I'd say!
  23. *
  24. *   Hope you find this program useful!
  25. *
  26.  
  27. #include "FileIO.ch"
  28. #define CRLF CHR(13) + CHR(10)
  29.  
  30. #define F_BLOCK 2048  // Buffer size.  Seems to work optimally between 512
  31.                       // and 4096 bytes.  A larger buffer seems to bog the
  32.                       // process down (which is the exact opposite of what
  33.                       // I had expected.)  This seems to point to an
  34.                       // inefficiancy in Clipper's string-handling abilities.
  35.                       // If anyone knows why this is, I'd be keen on hearing
  36.                       // from you!
  37.  
  38. PROCEDURE Main
  39.    
  40.    PARAMETER cFile  // Input parameter - filename.
  41.  
  42.    LOCAL cFlushBuffer := SPACE ( F_BLOCK )
  43.    LOCAL cBuffer := cFlushBuffer
  44.    LOCAL nBytes := F_BLOCK
  45.    LOCAL nPosition := 0, nFoundAt := 1, nNumLines := 0, nHandle
  46.    
  47.    IF cFile == NIL  // No file parameter included.
  48.       ? "Usage: LINCOUNT [pathname]filename"; ?
  49.       RETURN
  50.    ELSEIF .NOT. FILE ( cFile )
  51.       ? "Error: file " + cFile + " not found"; ?
  52.       RETURN
  53.    END IF
  54.  
  55.    nHandle := FOPEN ( cFile )
  56.  
  57.    DO WHILE nBytes == F_BLOCK   // Continue filling buffer until buffer
  58.                                 // doesn't fill up completely.
  59.       nBytes := FREAD ( nHandle, @cBuffer, nBytes )
  60.       DO WHILE .NOT. ( ( nFoundAt := AT ( CRLF, SUBSTR ; 
  61.                      ( cBuffer, nPosition, nBytes ) ) ) == 0 )
  62.          nPosition += nFoundAt + 1    // This loop cycles through the current
  63.          nNumLines += 1               // buffer until it doesn't find any 
  64.       END DO                          // more CR/LF's.
  65.       FSEEK ( nHandle, -1, FS_RELATIVE )   // Back up one byte in case the
  66.                                            // file pointer stops between a CR
  67.                                            // and an LF.
  68.       cBuffer := cFlushBuffer   // Reset the buffer.
  69.       nPosition := 0  // Reset last found position pointer.
  70.    END DO
  71.  
  72.    FCLOSE ( nHandle )
  73.  
  74.    ? STR ( nNumLines ) + " lines found in " + cFile; ?
  75.    
  76. RETURN
  77.