home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 344_01 / pb.c < prev    next >
Text File  |  1989-10-29  |  5KB  |  244 lines

  1.  
  2.  
  3. /*
  4.  *      HEADER:         ;
  5.  *    TITLE:          Phone Book;
  6.  *      DATE:           10/28/89;
  7.  *      DESCRIPTION:    "quick and dirty telephone directory to
  8.  *                      illustrate the use of blksplit() & stristr()";
  9.  *      VERSION:        1.0;
  10.  *      FILENAME:       PB.C;
  11.  *      USAGE:          PB [search string];
  12.  *      SEE-ALSO:       STRISTR.C, BLKSPLIT.C;
  13.  *      AUTHORS:        Michael Kelly;
  14.  *      WARNINGS:       "Requires STRISTR.OBJ and BLKSPLIT.OBJ.
  15.  *                      Telephone data file must be ASCII text with
  16.  *                      one record per line.
  17.  *                      Data file name is #defined as FILENAME";
  18.  *
  19.  *      COMMENTS:       Tested using TubroC V 2.0  Large Model.
  20.  *                      Should be easy port to any ANSI C;
  21.  */
  22.  
  23.  
  24.  
  25. /*
  26.  *    ***    Phone Book    ***
  27.  */
  28. #include <string.h>
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include "blksplit.h"
  32. #include "stristr.h"
  33.  
  34.  
  35. /*    #define DEBUG 1        */
  36.  
  37.  
  38. /*
  39.  *  maximum # of char * in array
  40.  */
  41. #define MAX_PHONE_NUMS 500
  42.  
  43.  
  44. /*
  45.  *  Phone Book data file
  46.  */
  47. #define FILENAME "phonebk.dat"
  48.  
  49. /*
  50.  *  maximum length of substring + 1
  51.  */
  52. #define REPLY_SIZE 128
  53.  
  54.  
  55. /*
  56.  *  module functions
  57.  */
  58. static void error_exit(char *errormsg, int line_no);
  59. static int get_data(void);
  60.  
  61. /*
  62.  *  global variables
  63.  */
  64. FILE *fp;
  65. char filename[] = FILENAME;
  66. char diskbuf[BUFSIZ];
  67. long length = 0L;
  68. char **phonenum;
  69. char *buffer;
  70.  
  71. /*
  72.  *  set record_sep to end of line delimiter(s) used on your file system
  73.  */
  74. #if defined(__MSDOS__)
  75. char record_sep[] = "\r\n";
  76. #else
  77. char record_sep[] = "\n";
  78. #endif
  79.  
  80. /*
  81.  *  Main
  82.  */
  83. int main(int argc, char *argv[])
  84. {
  85.     register int num_rec = 0, cur_rec = 0;
  86.     int matches = 0;
  87.     char reply[REPLY_SIZE] = "";
  88.  
  89.  
  90.     phonenum = (char **) calloc(MAX_PHONE_NUMS,sizeof(char *));
  91.     if(!phonenum)
  92.     error_exit("Not enough memory : Program terminating.",__LINE__);
  93.  
  94.     num_rec = get_data();
  95.  
  96.     if(num_rec < 1)
  97.     error_exit("Data file " FILENAME " invalid!",__LINE__);
  98.  
  99. #ifdef DEBUG
  100.  
  101.     for(cur_rec = 0;cur_rec < num_rec;cur_rec++)  {
  102.     size_t k;
  103.     k = strlen(phonenum[cur_rec]);
  104.     if(k) --k;
  105.  
  106.     printf("\n%s\nFirst char = %d  Last char = %d",
  107.         phonenum[cur_rec],phonenum[cur_rec][0],
  108.         phonenum[cur_rec][k]
  109.     );
  110.     }
  111.  
  112.     printf("\n\tNum records = %d\n",num_rec);
  113.  
  114.     gets(reply);
  115.  
  116. #endif
  117.  
  118.  
  119.     if(num_rec < 1)
  120.     error_exit("Data file " FILENAME " invalid!",__LINE__);
  121.  
  122.  
  123.     printf("\n\n\t\t\tP h o n e  B o o k\n");
  124.  
  125.     /*
  126.      *  command process loop
  127.      */
  128.     do  {
  129.  
  130.     if(argc < 2)  {
  131.  
  132.         printf("\n\t\t***   Press <Enter> to Quit   ***");
  133.         printf(
  134.         "\n\n\tEnter search string  { not case sensitive }\n\n\t>  "
  135.         );
  136.         gets(reply);
  137.         reply[REPLY_SIZE] = '\0';
  138.  
  139.     }
  140.  
  141.     else  {
  142.  
  143.         strncpy(reply,argv[1],REPLY_SIZE - 1);
  144.         --argc;
  145.  
  146.     }
  147.  
  148.     if(!*reply)
  149.         break;
  150.  
  151.     matches = 0;
  152.  
  153.     printf("\n");
  154.  
  155.     for(cur_rec = 0;cur_rec < num_rec;cur_rec++)
  156.         if(stristr(phonenum[cur_rec],reply))  {
  157.         matches++;
  158.         printf("\n%s",phonenum[cur_rec]);
  159.         }
  160.  
  161.     printf("\n\n\t%d record(s) matching \n\t>  %s\n",matches,reply);
  162.  
  163.     } while(*reply);
  164.  
  165.  
  166.  
  167.     if(phonenum)
  168.     free(phonenum);
  169.  
  170.     if(buffer)
  171.     free(buffer);
  172.  
  173.     return(EXIT_SUCCESS);
  174. }
  175.  
  176.  
  177. /*
  178.  *  support functions
  179.  */
  180.  
  181.  
  182. /*
  183.  *  display error message and exit
  184.  */
  185. static void error_exit(char *errormsg, int line_no)
  186. {
  187.     fprintf(stderr,"\n\t%s",errormsg);
  188.  
  189.  
  190. #ifdef DEBUG
  191.     if(line_no)
  192.     fprintf(stderr,"\t(# %d)\n",line_no);
  193. #endif
  194.  
  195.     exit(EXIT_FAILURE);
  196. }
  197.  
  198. /*
  199.  *  gets file size, allocates memory for and reads data file, then
  200.  *  calls blksplit() to store address of each record.
  201.  *
  202.  *  returns # of file lines read
  203.  *
  204.  */
  205. static int get_data()
  206. {
  207.  
  208.     fp = fopen(filename,"rb");
  209.     if(!fp)
  210.     error_exit("Cannot open " FILENAME,__LINE__);
  211.  
  212.     /*
  213.      *  determination of file length may not be portable
  214.      */
  215.     length = lseek(fileno(fp),0L,SEEK_END);
  216.     rewind(fp);
  217.  
  218.     if(length == -1L)
  219.     error_exit("Error determining input file length",__LINE__);
  220.  
  221.     else  {
  222.  
  223.     /*
  224.      *  allocate extra byte so block is NULL terminated
  225.      */
  226.     buffer = (char *) calloc(1,(size_t)(length + 1));
  227.     if(!buffer)
  228.         error_exit("Not enough memory : Program terminating.",__LINE__);
  229.  
  230.     if(setvbuf(fp,diskbuf,_IOFBF,BUFSIZ))
  231.         error_exit("Data file buffer error",__LINE__);
  232.  
  233.     if(!fread(buffer,(size_t)length,1,fp))
  234.         error_exit("Error reading data file.",__LINE__);
  235.  
  236.     fclose(fp);
  237.  
  238.     }
  239.  
  240.     return(blksplit(buffer,phonenum,record_sep,MAX_PHONE_NUMS));
  241. }
  242.  
  243.  
  244.