/* * looking.c * * A sample program using bsearch() library. * * looking key [file]... * * key: specify an integer value to be searched * may be in decimal, octal(0...), hex(0x...). * * file: specify input files (optional) */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <limits.h> /* * structure define for variable length array */ #define INITSIZE (16 * sizeof(int)) typedef struct arry { int cursize; int nmemb; int *data; } array_t; /* * add an element to an array pointed to by array_t *a */ array_t *add_member(array_t *a, int memb) { int *p; long newsize; if ((a->nmemb + 1) * sizeof(int) > a->cursize) { newsize = (long)a->cursize * 2L; if (newsize >= INT_MAX) { fprintf(stderr, "too many data\n"); exit(1); } a->cursize = (int)newsize; if ((p = realloc(a->data, (size_t)a->cursize)) != NULL) a->data = p; else { fprintf(stderr, "out of memory\n"); exit(1); } } a->data[a->nmemb++] = memb; return a; } /* * skip leading spaces. */ char *remblank(char *p) { while (isspace(*p)) ++p; return p; } /* * get next line and pick integer data from it */ #define MAXLINE 1024 array_t *read_array(FILE *fp, array_t *a) { char line[MAXLINE]; char *p; char *endp = NULL; /* make silly lint happy */ int val; if (a == NULL) { if ((a = malloc(sizeof(array_t))) == NULL) { fprintf(stderr, "out of memory %u\n", sizeof(array_t)); exit(1); } a->cursize = INITSIZE; a->nmemb = 0; if ((a->data = malloc(INITSIZE)) == NULL) { fprintf(stderr, "out of memory %u", INITSIZE); exit(1); } } while (fgets(line, sizeof(line), fp) != NULL) { for (p = remblank(line); *p != '\0'; p = remblank(endp)) { val = (int)strtol(p, &endp, 0); if (p == endp) { fprintf(stderr, "data error: %s", line); fprintf(stderr, " %*s^\n", endp - line, ""); exit(1); } a = add_member(a, val); } } return a; } void print_array(array_t *a) { int i; for (i = 0; i < a->nmemb; ++i) printf("%d\n", a->data[i]); } int cmp_int(const void *p0, const void *p1) { return *(const int *)p0 - *(const int *)p1; } /* * Mail command driver */ int main(int argc, char **argv) { FILE *fp; int i; int key; char *endp; array_t *ary = NULL; if (argc == 1) { /* no argument */ fprintf(stderr, "useage: looking key [file]...\n"); exit(1); } key = (int)strtol(argv[1], &endp, 0); if (argv[1] == endp) { fprintf(stderr, "invalid number: %s\n", argv[1]); exit(1); } --argc; ++argv; if (argc == 1) /* no file is specified */ ary = read_array(stdin, ary); else { for (i = 1; i < argc; ++i) { if ((fp = fopen(argv[i], "r")) == NULL) { fprintf(stderr, "%s: can't open %s\n", argv[0], argv[1]); continue; } ary = read_array(fp, ary); fclose(fp); } } qsort(ary->data, ary->nmemb, sizeof(int), cmp_int); if (bsearch(&key, ary->data, ary->nmemb, sizeof(int), cmp_int) != NULL) printf("%d yes\n", key); else printf("%d no\n", key); free(ary->data); free(ary); return 0; } |