
/***********************************************
* CreatRec.C
*
*  A method of handling the complex memory
*  allocation required to create an array of
*  character arrays in memory
*
*  The function declaration required is:
*    char **CreateRecord(int nfields,
*               int flen[], int InitString);
*  where: nfields is the number of fields or
*      strings to be created flen[] is an
*      array of nfields-many ints, where each
*      array element is the desired length
*      of the corresponding field; InitString
*      is the value to use when initializing the
*      string space allocated by the function.
*
*  Returns: (char **).
*  The programmer should use this pointer to
*  access the strings created, and to free the
*  allocated memory when finished.
***********************************************/

#include <stdio.h>
#include <conio.h>
#include <alloc.h>
#include <mem.h>
#include <stdlib.h>

char **CreateRecord(int nfields, int flen[],
                   int InitString)
{
   char **field; /* this value is returned */
   char *p;
   int i=0, recsize=0, memsize;

   while(i<nfields){
        recsize += flen[i++]; /* add up field sizes */
        }
   recsize += nfields; /* add space for a terminator for each field */

  /* total to allocate includes space for strings
     and pointers to them: */
  memsize = nfields*sizeof(char *) +
                recsize*sizeof(char);
  field = (char **)malloc(memsize);
  if(!field){
       #ifdef ERR_INTERNAL
            puts("Malloc failure in CreateRecord()");
            exit(1); /* abort on failure */
       #else
            return NULL; /* return warning to caller */
       #endif
       }
  /* initialize strings */       
  memset(field,InitString,memsize);

  /* set p to point to the first byte
     beyond the last pointer needed: */
  p = (char *)&field[nfields];
  for(i=0; i<nfields; i++){
       field[i] = p; /* initialize the
                        pointer array */
       p = &p[ flen[i] ]; /* get address of
                          last char of the field */
       *p = '\0'; /* terminate the string */
       p++; /* next string start address */
       }
  return field;
} /* CreateRecord() */


/******************************************************
     A Example of a Routine that Uses CreateRecord()
 ******************************************************/

#define ArraySize(x) ( sizeof(x)/sizeof(x[1]) )
/* by ArtS: October, 1990. a general purpose macro to provide
a count of the number of elements in any given array.
NOTE that this works for
        char c[] = "Art was here"; ...c is an array
but NOT for
        char *c =  "Art was here"; ...c is a pointer!
*/


#define SPACE 32

/* This is the declaration you need to use CreateRecord(): */
char **CreateRecord(int nfields, int flen[], int InitString);

/* A sample database fieldset: */
char *label[] = { /* labels for example database record */
     "    FName",
     "    LName",
     "  Address",
     "     City",
     "    State",
     "      Zip",
     "  Remarks"
     };
/* Field lengths for this sample database: */
int array[] = { 20, 20, 30, 25, 2, 10, 50 };


void main(void){
     char **set;
     int fieldcount;
     int i;

     puts("\nSample calls to CreateRecord() for allocating string arrays\n");

     puts("Initialize a database record to blanks:");
     fieldcount = ArraySize(array);
     set = CreateRecord(fieldcount, array, SPACE);
     if(!set){
          printf("Error allocating memory for record\n");
          exit(1);
          }
     for(i=0; i<fieldcount; i++){
          printf(" %s: [%s]\n", label[i], set[i] );
          }
     puts("\nPress Key..."); getch();

     puts("Initialize a database record to underline characters:");
     fieldcount = ArraySize(array);
     set = CreateRecord(fieldcount, array, '_');
     if(!set){
          printf("Error allocating memory for record\n");
          exit(1);
          }
     for(i=0; i<fieldcount; i++){
          printf(" %s: [%s]\n", label[i], set[i] );
          }
     puts("\nPress Key..."); getch();

     free(set);

     puts("Initialize a set if five strings of length 12 to 'A':");
     for(i=0; i<5; i++){
          array[i] = 12; /* set all field lengths to 12 */
          }
     set = CreateRecord(5, array, 'A' );
     if(!set){
          printf("Error allocating memory for record\n");
          exit(1);
          }
     for(i=0; i<5; i++){
          printf(" item %d: [%s]\n", i, set[i] );
          }
     }/* main */

