ssdken@jarthur.Claremont.EDU (Ken Nelson) (01/17/90)
Hello, I need source code for the ansi function 'strtok'. We are porting from a system that has it, to one that doesn't. Thanks for any help. Ken Nelson Principal Engineer Software Systems Design 3627 Padua Avenue Claremont, CA 91711 (714) 624-2402
Lynn.Lively@p4694.f506.n106.z1.fidonet.org (Lynn Lively) (01/20/90)
In an article of <16 Jan 90 22:40:10 GMT>, ssdken@jarthur.Claremont.EDU (Ken Nelson) writes: KN>From: ssdken@jarthur.Claremont.EDU (Ken Nelson) KN>Date: 16 Jan 90 22:40:10 GMT KN>Organization: Harvey Mudd College, Claremont, CA KN>Message-ID: <3796@jarthur.Claremont.EDU> KN>Newsgroups: comp.lang.c KN> KN>Hello, KN> KN> I need source code for the ansi function 'strtok'. We are porting KN> from a system that has it, to one that doesn't. KN> KN> KN> Thanks for any help. KN> KN> KN> Ken Nelson KN> Principal Engineer KN> Software Systems Design KN> 3627 Padua Avenue KN> Claremont, CA 91711 KN> (714) 624-2402 Ken, Here is a function that should be able to stand in for strtok() took me about half an hour to write. I'm including a test program too. It seems to work as expected, but you may want to check it out a bit more before you trust it in production. Your Servant, Lynn ------------------------------------------------------------------------- #include <stdio.h> #include <string.h> char * mytok (char * object, char * delims); void main () { char s[256]; char delims[256]; char * wk_ptr; while (1) { printf ("Enter String to search:\n"); gets (s); printf ("Enter Delimeters to search for:\n"); gets (delims); wk_ptr = s; while ((wk_ptr = mytok (wk_ptr, delims)) != NULL) { printf ("String found: '%s'\n", wk_ptr); wk_ptr = NULL; } } } /* * Works like strtok() */ char * mytok (char * object, char * delims) { static char * obj_ptr = NULL; static char * end_ptr = NULL; char * wk_ptr; char * min_ptr; if (object != NULL) { obj_ptr = object; end_ptr = object + strlen (object); } if (obj_ptr == end_ptr) { return (NULL); } min_ptr = end_ptr; while (*delims != '\0') { wk_ptr = strchr (obj_ptr, *delims++); if (wk_ptr != NULL) { min_ptr = (wk_ptr < min_ptr) ? wk_ptr : min_ptr; } } if (min_ptr != end_ptr) { wk_ptr = obj_ptr; obj_ptr = min_ptr + 1; while (obj_ptr < end_ptr) { if (*obj_ptr == *min_ptr) { *obj_ptr++ = '\0'; } else { break; } } *min_ptr = '\0'; } else { wk_ptr = obj_ptr; obj_ptr = end_ptr; } return (wk_ptr); }
chris@mimsy.umd.edu (Chris Torek) (01/21/90)
Since I dislike functions with hidden state, my strtok() consists of the state plus a call to a more fundamental function which I call `strtoken'. Here are both of those, plus strsep(). The comments should enable readers to figure out what these do. Note that strsep, intended for things like /etc/passwd lines, and strtoken, intended for use within the C library itself (which may not use strtok since strtok has hidden state), are not ANSI standard functions. Indeed, strtoken cannot be an ANSI standard function, since its six character monocase equivalent name is `strtok'. (Despite the Berkeley copyright, these particular implementations are not yet on any Berkeley machine. Well, maybe they are; I might have forgotten putting them there.) [strsep.c] /* * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include <string.h> #include <sys/stdc.h> #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "%W% (Berkeley) %G%"; #endif /* LIBC_SCCS and not lint */ /* * Get next token from string s (NULL on 2nd, 3rd, etc. calls), * where tokens are possibly empty strings separated by any character * from delim. Writes NULs into s to end tokens. delim need not * remain constant from call to call. */ char * strsep(s, delim) char *s; const char *delim; { static char *last; if (s != NULL) last = s; return (strtoken(&last, delim, 0)); } [strtok.c] /* * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include <string.h> #include <sys/stdc.h> #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "%W% (Berkeley) %G%"; #endif /* LIBC_SCCS and not lint */ /* * Get next token from string s (NULL on 2nd, 3rd, etc. calls), * where tokens are nonempty strings separated by runs of * chars from delim. Writes NULs into s to end tokens. delim need not * remain constant from call to call. */ char * strtok(s, delim) char *s; const char *delim; { static char *last; if (s != NULL) last = s; return (strtoken(&last, delim, 1)); } [strtoken.c] /* * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include <string.h> #include <sys/stdc.h> #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "%W% (Berkeley) %G%"; #endif /* LIBC_SCCS and not lint */ /* * Get next token from string *stringp, where tokens are (possibly empty) * strings separated by characters from delim. Tokens are separated * by exactly one delimiter iff the skip parameter is false; otherwise * they are separated by runs of characters from delim, because we * skip over any initial `delim' characters. * * Writes NULs into the string at *stringp to end tokens. * delim will usually, but need not, remain constant from call to call. * On return, *stringp points past the last NUL written (if there might * be further tokens), or is NULL (if there are definitely no more tokens). * * If *stringp is NULL, strtoken returns NULL. */ char * strtoken(stringp, delim, skip) register char **stringp; register const char *delim; int skip; { register char *s; register const char *spanp; register int c, sc; char *tok; if ((s = *stringp) == NULL) return (NULL); if (skip) { /* * Skip (span) leading delimiters (s += strspn(s, delim)). */ cont: c = *s; for (spanp = delim; (sc = *spanp++) != 0;) { if (c == sc) { s++; goto cont; } } if (c == 0) { /* no token found */ *stringp = NULL; return (NULL); } } /* * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). * Note that delim must have one NUL; we stop if we see that, too. */ for (tok = s;;) { c = *s++; spanp = delim; do { if ((sc = *spanp++) == c) { if (c == 0) s = NULL; else s[-1] = 0; *stringp = s; return (tok); } } while (sc != 0); } /* NOTREACHED */ } -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris