home *** CD-ROM | disk | FTP | other *** search
/ C by Discovery (4th Edition) / C_By_Discovery_4th_Edition.tar / C_By_Discovery_4th_Edition / _DISK_ / ch10 / fseek.c < prev    next >
C/C++ Source or Header  |  2005-06-16  |  5KB  |  152 lines

  1. /*               fseek.c
  2.  *
  3.  *   Synopsis  - Opens a file and displays records at a user's
  4.  *               request.
  5.  *   Objective - To introduce the standard library functions 
  6.  *               fseek() and ftell().
  7.  */
  8.  
  9. /* Include Files */
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12.  
  13. /* Constant Definitions */
  14. #define BUF_SIZE  80
  15.  
  16. /* Type Declarations */
  17. struct trans {
  18.      int t_type;
  19.      char payee_memo[BUF_SIZE];
  20.      double amount;
  21.      unsigned tax_deduct:1;
  22.      unsigned cleared:1;
  23. };
  24.  
  25. /* Function Prototypes */
  26. void print_trans( struct trans *outtrans );
  27. /*   PRECONDITION:  The parameter outtrans contains the address of a 
  28.  *                  struct trans declared by the calling function.
  29.  *   POSTCONDITION: Displays the contents of the structure pointed to 
  30.  *                  by outtrans on standard output. Each field is 
  31.  *                  separated with a vertical bar character.
  32.  */
  33.  
  34. void browse( FILE *fp, long numrecs );
  35. /*   PRECONDITION:  fp contains the address of a FILE *. numrecs 
  36.  *                  contains the number of records.
  37.  *   POSTCONDITION: Accepts input of record numbers, finds and 
  38.  *                  displays the records until the user signals quit 
  39.  *                  with a 'Q'.
  40.  */
  41.  
  42. int read_trans( struct trans * trans_ptr, FILE * fp);
  43. /*   PRECONDITION:  The parameter trans_ptr contains the address of a 
  44.  *                  struct trans declared by the calling function. fp
  45.  *                  contains the address of a FILE *.
  46.  *   POSTCONDITION: Reads a single transaction from the file 
  47.  *                  associated with fp and stores it in the structure 
  48.  *                  pointed to by trans_ptr.
  49.  */
  50.  
  51. long int getnumrecs( FILE *fp );
  52. /*   PRECONDITION:  fp contains the address of a FILE *. 
  53.  *   POSTCONDITION: Calculates the number of records in the file by 
  54.  *                  getting  the total length of the file and dividing 
  55.  *                  by the number of bytes in a record.
  56.  */
  57. int main( void )
  58. {
  59.      FILE *fp;
  60.      long int totalrec;
  61.                                                            /* Note 1 */
  62.      if (( fp = fopen( "transact", "r+" )) == NULL ) {
  63.           printf( "Transaction file couldn't be opened.\n" );
  64.           exit( 1 );
  65.      }
  66.      totalrec = getnumrecs( fp );
  67.      if ( totalrec == -1L ) {
  68.           fprintf( stderr, "Error with transaction file\n" );
  69.           exit( 1 );
  70.      }
  71.  
  72.      printf( "Transaction Browser\n" );
  73.      printf( "Enter the record number you want to see " );
  74.      printf( "or 'Q' to quit.\n" );
  75.      browse( fp, totalrec );
  76.      return 0;
  77. }
  78.  
  79. /*******************************read_trans()********************/
  80.                                                         /* Note 2 */
  81. int read_trans( struct trans * trans_ptr, FILE * fp)
  82. {
  83.      int retval;
  84.  
  85.      retval = fread( trans_ptr, sizeof( *trans_ptr ), 1, fp );
  86.      return ( retval );
  87. }
  88.  
  89. /*******************************print_trans()*******************/
  90.  
  91. void print_trans( struct trans *outtrans )                                                         /* Note 3 */
  92. {
  93.      /* Cleared field */
  94.      if ( outtrans->cleared )
  95.           printf( "C | " );
  96.      else
  97.           printf( "  | " );
  98.  
  99.      /* Transaction type */
  100.      if (( outtrans->t_type =='D' ) || ( outtrans->t_type == 'W' ) || ( outtrans->t_type == 'I' ))
  101.           printf( "%4c | ", outtrans->t_type );
  102.      else
  103.           printf( "%4d | ", outtrans->t_type );
  104.  
  105.      /* tax_deduct field */
  106.      if ( outtrans->tax_deduct )
  107.           printf( " T | " );
  108.      else
  109.           printf( "   | " );
  110.  
  111.      printf( "%10.2f  | ", outtrans->amount );
  112.      printf( "%s", outtrans->payee_memo );
  113. }
  114.  
  115. /*******************************browse()************************/
  116.  
  117. void browse( FILE *fp, long numrecs )
  118. {
  119.      int recnum;
  120.  
  121.      struct trans transact;
  122.  
  123.      printf( "Transaction number: " );
  124.      while ( scanf( "%d", &recnum )) {                  /* Note 4 */
  125.           if ( recnum >= numrecs )
  126.                printf( "Enter a number between 0 and %d\n",numrecs-1 );
  127.           else {
  128.                                                         /* Note 5 */
  129.                fseek( fp, ( long ) recnum*sizeof( transact ), 0 );
  130.                if ( read_trans( &transact ,fp ))
  131.                     print_trans( &transact );
  132.                else
  133.                     printf( "Transaction %d not found.\n", recnum );
  134.           }
  135.           printf( "Next transaction Number: " );
  136.      }
  137. }
  138.  
  139. /*******************************getnumrecs()********************/
  140.  
  141. long int getnumrecs( FILE *fp )
  142. {
  143.      long int numbytes;
  144.  
  145.      fseek( fp, ( long ) 0, 2 );                        /* Note 6 */
  146.      numbytes = ftell( fp );                            /* Note 7 */
  147.      if ( numbytes != -1 )
  148.           return ( numbytes/sizeof( struct trans ));
  149.      else
  150.      return ( -1L );
  151. }
  152.