home *** CD-ROM | disk | FTP | other *** search
/ Media Share 13 / mediashare_13.zip / mediashare_13 / ZIPPED / PROGRAM / SNIP9404.ZIP / STRUCFIL.C < prev    next >
C/C++ Source or Header  |  1994-04-03  |  5KB  |  191 lines

  1. /*******************************************************************
  2.  * Generic structure <> disk file manipulations. These functions
  3.  * form a basic template for reading and writing structures to a 
  4.  * sequential file. This template is probably most useful for files
  5.  * with 500 or less records and eliminates the need for a more 
  6.  * elaborate file handler such as C-Tree, DB-Vista, Mix etc.
  7.  * Routines to put data in the struct is out of scope here.
  8.  * Written by Lynn Nash 8/28/91 and donated to the public domain.
  9.  */
  10. #include <io.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14.  
  15. #ifndef ERROR
  16. #define ERROR -1
  17. #define OK     0
  18. #endif
  19.  
  20. #ifndef TRUE
  21. #define TRUE 1
  22. #define FALSE !TRUE
  23. #endif
  24.  
  25. /* make sure the record structure is byte aligned */
  26.  
  27. #if defined(__TURBOC__)
  28.  #pragma option -a-
  29. #elif defined(__ZTC__)
  30.  #pragma ZTC align 1
  31. #else /* MSC/QC/WATCOM/METAWARE */
  32.  #pragma pack(1)
  33. #endif
  34.  
  35. static struct blackbook {
  36.     int delete_flag;        /* 0 = active  -1 = deleted */
  37.     int recordnum;          /* a sequential number in the file */
  38.    /* The data fields in asciiz.  */
  39.     char firstname[11];         
  40.     char lastname[16];         
  41.     char addr[26];          
  42.     char city[16];
  43.     char state[3];
  44.     char zip[10];
  45.     char phone[11];
  46. } rec, oldrec;             /* 97 byte record  * 2 */
  47.  
  48. #pragma pack()
  49.  
  50. /*-------------------- general globals ---------------------*/
  51.  
  52. static long cur_rec = 0;      /* the current record number */
  53. static FILE *fsptr = NULL;    /* fixed record data file pointer */
  54.  
  55. /* if file exists open in read/write mode else create file */
  56.  
  57. FILE * open_file(char *filename)
  58. {
  59.       if (access(filename, 0) == 0)
  60.             fsptr = fopen(filename, "rb+"); 
  61.       else  fsptr = fopen(filename, "wb+"); 
  62.       return fsptr;                       /* return the file pointer */
  63.  
  64. /* add new records to the data file */
  65.  
  66. int datadd(void)
  67. {
  68.       if (fsptr)
  69.       {
  70.             if (fseek(fsptr, 0L, SEEK_END) != 0)
  71.                   return ERROR;  /* seek failure */
  72.             rec.delete_flag = 0; /* active record tag */
  73.             rec.recordnum = (int) (ftell(fsptr) / 
  74.                   (long) sizeof(struct blackbook));
  75.             if (fwrite(&rec, sizeof(struct blackbook), 1, fsptr) != 1)
  76.             {
  77.                   return ERROR; /* write error */
  78.             }
  79.             else
  80.             {
  81.                   /* put your clean up code here */ 
  82.                   return OK;
  83.             }
  84.       }
  85.       return ERROR;
  86. }
  87.  
  88. /* tag the last record read in the file as deleted */
  89.  
  90. int data_delete(void)
  91. {
  92.       if (fsptr)
  93.       {
  94.             if (fseek(fsptr, (long) sizeof(struct blackbook) * -1L,
  95.                   SEEK_CUR) != 0)
  96.             {
  97.                   return ERROR;
  98.             }
  99.             rec.delete_flag = -1;   /* tag the record as deleted */
  100.             if (fwrite(&rec, sizeof(struct blackbook), 1, fsptr) != 1)
  101.                   return ERROR;
  102.             else  return OK;
  103.       }
  104.       return ERROR;
  105. }
  106.  
  107. /* read a random structure. If successful the global cur_rec will 
  108.  * contain the number of the last record read & it can be compared
  109.  * to the number in the struct as a double check (belt & suspenders)
  110.  */
  111.  
  112. int data_read(long recnum)
  113. {
  114.       if (fseek(fsptr, (long) sizeof(struct blackbook) * recnum,
  115.             SEEK_SET) != 0)
  116.       {
  117.             return ERROR;
  118.       }
  119.       cur_rec = recnum; /* keep tabs on record pointer in global */  
  120.  
  121.       /* now read the record into save struct*/
  122.  
  123.       if (fread(&oldrec, sizeof(struct blackbook), 1, fsptr) != 1)
  124.       {
  125.             return ERROR;
  126.       }
  127.       else                          /* copy save struct to edit struct */
  128.       {
  129.             memcpy(&rec, &oldrec, sizeof(struct blackbook));
  130.             return OK;
  131.       }
  132. }
  133.  
  134. /* rewrite the last read record back to disk */
  135.  
  136. int data_update(void)
  137. {
  138.       if (memcmp(&rec, &oldrec, sizeof(struct blackbook)) == 0)
  139.             return TRUE;  /* no update needed */
  140.  
  141.       /* back up one record before writing */
  142.  
  143.       if (fseek(fsptr, (long) sizeof(struct blackbook) * -1L, 
  144.             SEEK_CUR) != 0)
  145.       {
  146.             return ERROR; /* seek error */ 
  147.       }
  148.  
  149.       /* now write the record */
  150.  
  151.       if (fwrite(&rec, sizeof(struct blackbook), 1, fsptr) != 1)
  152.             return ERROR; /* write error */
  153.       return OK;
  154. }
  155.  
  156. /* get the next valid record in the file */
  157.  
  158. int read_forward(void)
  159. {
  160.       do
  161.       {
  162.             cur_rec++; /* upcount the record number */
  163.             if (data_read(cur_rec) != 0)
  164.             {
  165.                   cur_rec--; /* decrement the record number */
  166.                   return ERROR;
  167.             }
  168.       } while (oldrec.delete_flag != 0); /* record read was deleted */
  169.       return OK;
  170. }
  171.  
  172. /* get the previous valid record in the file */
  173.  
  174. int read_backward(void)
  175. {
  176.       do
  177.       {
  178.             cur_rec--;  /* decrement the record number */
  179.             if (cur_rec >= 0)
  180.             {
  181.                   if ( data_read(cur_rec) != 0 )
  182.                   {
  183.                         cur_rec++; /* increment the record number */
  184.                         return ERROR;
  185.                   }
  186.             }  
  187.       } while (oldrec.delete_flag != 0); /* record read was deleted */
  188.       return OK;
  189. }
  190.