Category : Files from Magazines
Archive   : CLM89DEC.ZIP
Filename : SEARCH.C

 
Output of file : SEARCH.C contained in archive : CLM89DEC.ZIP
/* Incremental String Search, by Jim Kerr. */
/* */
/* This file contains three functions GETKEY, GET_RANGE, and */
/* INC_SEARCH that allow incremental searching of string arrays. */
/* To use the routines, first #DEFINE the constants MAXSTR and */
/* MAXLEN as described below. Then call function INC_SEARCH with */
/* INC_SEARCH(,,&,&). */
/* See the description of INC_SEARCH in this file for return */
/* value and other info. */

#define MAXSTR 25 /* maximum number of strings in array */
#define MAXLEN 30 /* maximum length of each string */
#define ESC 27 /* ASCII code for Escape */

/* The value of the manifest constant MIXCASE determines whether */
/* string comparisons are case-sensitive. If MIXCASE is nonzero, */
/* comparisons are case-sensitive, otherwise not. */
#define MIXCASE 0
#if MIXCASE
#define CASEMOD(x) x
#else
#define CASEMOD toupper
#endif

typedef char STR[MAXLEN+1]; /* definition of type STR */
typedef STR STARRAY[MAXSTR]; /* ... of type STARRAY */

/* Function GETRANGE searches ARRAY[0] through ARRAY[LAST_INDEX] */
/* for an entry beginning with character SEARCH_CHAR. If a match */
/* is found, the integers pointed to by PTR_FIRST and PTR_LAST */
/* give the range of array locations that yield a match, and */
/* GET_RANGE returns 1. If no match is found, GET_RANGE returns */
/* 0. Case sensitivity is determined by the value of the */
/* constant MIXCASE. */

int get_range(search_char,array,last_index,ptr_first,ptr_last)
char search_char;
STR *array;
int last_index, *ptr_first, *ptr_last;
{
int j, k; /* loop variables */
int found; /* indicates if a match has been found */

search_char = CASEMOD(search_char);
for (j=0; j<=last_index; j++) /* seek first match */
if (found = CASEMOD(array[j][0]) == search_char)
{ /* a match has been found at index j */
k = j; /* store value in k */
break;
}
if (found)
{ /* a match has been found at index k; determine its extent */
for (j=k; CASEMOD(array[j+1][0]) == search_char; j++)
; /* set j to last matching index */
*ptr_first = k;
*ptr_last = j;
return(1);
}
return(0);
}

/* Function GETKEY() reads a character from the keyboard. The */
/* action taken depends upon the character entered in this way: */
/* */
/* char. code return value other action */
/* ========= ============ ============= */
/* \' or \" 0 no echo */
/* others in */
/* 32-125 same echoed */
/* others - ignored */

int getkey(void)
{ char ch;

while (1)
{
if ((ch = getch()) == '\'' || ch == '\"')
return(0);
if (ch == ESC || ch == '\r' || ch >= 32 && ch <= 125)
{ putch(ch);
return(ch);
}
if (ch == 0) getch(); /* discard function key input */
}
}

/* Function INC_SEARCH uses the keyboard routine GETKEY() to */
/* obtain a character from the user. Each time a key is pressed, */
/* INC_SEARCH determines the range of indices in array ARR that */
/* are compatible with the current search string. If there are */
/* none, INC_SEARCH returns 0. If only one entry is compatible, */
/* INC_SEARCH returns 1, and the integers pointed to by PTR_START */
/* and PTR_END both contain the index of the matching entry. If */
/* the user presses before a unique match is found, */
/* INC_SEARCH returns 1, and PTR_START and PTR_END point to the */
/* first and last indices that yield a partial match. If the */
/* key is pressed at any time, the search is aborted, and */
/* INC_SEARCH returns -1. */

int inc_search(arr,imax,ptr_start,ptr_end)
STARRAY arr;
int *ptr_start,*ptr_end;
{ int first,last,ch; /* parameters for GET_RANGE call */
int OK = 1; /* return value of GET_RANGE; defaults to 1 */
int start,end; /* first and last indices that yield a match */
STR *base; /* starting location for search */

end = imax;
base = arr; start = 0;
while ( (ch = getkey()) != '\r' && ch != ESC
&& (OK = get_range(ch,base,imax,&first,&last)))
{ /* No CR or ESC has been entered,
and the list of matches is nonempty */
end = start + last; /* adjust value of end */
start += first; /* and of start */
if (strcmp(arr[start],arr[end])==0)
break; /* abort loop if there's a unique match. */
else /* a match has been found, but it's not unique */
{ /* adjust start locn. for search */
base = &base[first][1];
imax = last - first; /* adjust max search index */
}
}
if (ch == ESC)
return(-1); /* return -1 if search was aborted */
/* else return values as described above */
*ptr_start = start;
*ptr_end = end;
return(OK);
}

/* The code that appears from this point on is used solely to */
/* demonstrate the incremental search facility. */

STARRAY arr =
{ "Anderson","Bradley","Burke","Byrnes","Federico","Fikar",
"Frazer","Geary","Grando","Haas","Lehr","Lemke","Mahoney",
"Martin","Martino","Milne","Milnor","Montgomery","Rivera",
"Rivers"};

/* DO_AGAIN presents the user with the prompt 'Do again? (Y/N)' */
/* and waits until either 'Y' or 'N' is entered. The character */
/* selected is the return value. */

int do_again(void)
{ char ch;

printf("\n Do again ? (Y/N) ");
while ((ch = toupper(getch())) != 'Y' && ch != 'N')
;
putch(ch);
return(ch);
}

main()
{ int k,maxindex,start,end;

/* print the array to be searched */
for (k=0; k<=MAXSTR-1; k++)
if (arr[k][0] == 0)
{ maxindex = k-1;
printf("\n");
break;
}
else printf("%-20s",arr[k]);
for (k=1; k<=80; k++)
putch('=');
/* perform incremental search */
do {
printf("\n Enter a search string : ");
switch (inc_search(arr,maxindex,&start,&end)) {
case -1 : printf ("\n Aborted by user.");
break;
case 0 : printf("\n No matches found.");
break;
case 1 : printf("\n Matches are : \n");
for (k=start; k<=end; k++)
printf("%-20s",arr[k]);
printf("\n");
}
}
while (do_again() == 'Y');
}



  3 Responses to “Category : Files from Magazines
Archive   : CLM89DEC.ZIP
Filename : SEARCH.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/