// thus on Thu, 15 Jan 1998 16:13:11 -0600, Akuma/Chris virtually wrote: > ok, in the way of str_cmp, str_dup, strn_cmp, et al. > I have created a str_str() function that works correctly. > Begin Code (put it in utils.c)------- // str_str: a case-insensitive version of strstr() // scans arg1 for the first occurrence of the substring arg2 // returns a pointer to the point in arg1 where arg2 begins. // If arg2 does not occur in arg1, str_str returns NULL. // Written by Akuma the Raging Coder > char *str_str(char *arg1, char *arg2) > { > register int iptr; > register int len1; > register int len2; > if (!arg1 && !arg2) > { log("NULL arg1 and arg2 passed to %s().", __FUNCTION__); return NULL; } > else if (!arg1) > { log("NULL arg1 passed to %s().", __FUNCTION__); return NULL; } > else if (!arg2) > { log("NULL arg2 passed to %s().", __FUNCTION__); return NULL; } > len1 = str_len(arg2); > len2 = str_len(arg1); > // if str_len(arg2) is greater than str_len(arg1), > // then arg2 can't be substring of arg1 > if (len1 > len2) > return NULL; > else if (len1 == len2) { > if (!str_cmp(arg1, arg2)) > return (arg1); > else return NULL; > } > for (iptr = 0; iptr <= len2 - len1; iptr++) { > if (LOWER(*arg2) == LOWER(*(arg1+iptr)) && > is_abbrev(arg2, (arg1 + iptr))) > return (arg1+iptr); > } > // Obviously we reached the end, and nothing was found. > return NULL; > } > -----End Code A couple of issues here, by using str_len to get length of arg2 and arg1 for the initial check, you are traversing the two strings, and then by doing a str_cmp you're partially traversing it again, and THEN with is_abbrev you're partially traversing again. Only in the best case scenario (i.e. it just isn't there), you end up with the shortest execution time. With the following NULL checks, you can avoid repeated traversals, also if you look in glibc2, you'll see a nice implementation by van den Berg. d. /* * I hacked the following, it may contain missing sanity * checking since I wrote it in vi instead of emacs */ char *str_str (const char *haystack, const char *needle) { register const char *h, *n; const char *hm; if (!haystack || !needle) return NULL; n = needle; for (h = haystack; *h; h++) { if (*h == *n) { hm = h; /* set mark start of substring search */ while (*h && *n) { if (LOWER(*h) != LOWER(*n)) /* substring does not match */ break; h++; n++; } if (*n) { /* needle not terminated? start over */ n = needle; /* reset needle */ h = hm; /* reset haystack */ } else /* needle found, return start of substring */ return (char *) hm; } } return NULL; /* nothing found */ } int main () { char *p; p = str_str ("hello world", "world"); printf ("%s\n", p ? p : "NULL"); p = str_str ("ab", "a"); printf ("%s\n", p ? p : "NULL"); p = str_str ("hello", "ab"); printf ("%s\n", p ? p : "NULL"); p = str_str ("ab", "world"); printf ("%s\n", p ? p : "NULL"); p = str_str ("word world world-wonder", "world-wonder"); printf ("%s\n", p ? p : "NULL"); return 1; } +------------------------------------------------------------+ | Ensure that you have read the CircleMUD Mailing List FAQ: | | http://democracy.queensu.ca/~fletcher/Circle/list-faq.html | +------------------------------------------------------------+
This archive was generated by hypermail 2b30 : 12/15/00 PST