home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c
- Path: sparky!uunet!uunet.ca!canrem!telly!druid!darcy
- From: darcy@druid.uucp (D'Arcy J.M. Cain)
- Subject: Re: strtok
- Message-ID: <1993Jan5.123430.5849@druid.uucp>
- Date: Tue, 5 Jan 1993 12:34:30 GMT
- Distribution: usa
- References: <1992Dec31.045902.2025@mcs.drexel.edu> <bibhas.725836376@femto.engr.mun.ca> <1iab2aINNlmn@parlo.hal.COM>
- Organization: D'Arcy Cain Consulting
- Lines: 138
-
- paul@hal.COM (Paul Sander) writes:
- >Robert Osborne posted a strtok replacement to comp.lang.c on September 12,
- >1991 that returns strtok's global state in a parameter to the caller, making
- >it reentrant. The message-ID is 1395@isgtec.UUCP, and I have copies of it
- >if anyone is interested.
-
- Here's one I wrote based on Henry Spencer's strtok code. I had to change
- the name since the semantics are completely different than the standard.
-
- /*
- * xstrtok.c
- * Written by D'Arcy J.M. Cain
- * based on code by Henry Spencer
- * modified to assume an ANSI compiler by D'Arcy J.M. Cain
- * because strtok is a little brain dead about multiple calls
- * this is a modified version which carries the pertinent information
- * in a structure. This allows more than one string to be parsed
- * at the same time (the code is re-entrant.)
- *
- * Get next token from string x->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. If quote is set then quotes (single
- * or double) are respected.
- *
- * structure in string.h should look like this:
- * typedef struct {
- * char *scanpoint; / * filled in by xstrtok * /
- * char *str2parse; / * string to parse - set for first call * /
- * const char *delim; / * string of delimiters * /
- * int quote; / * respect quoting if set * /
- * } XSTRTOK;
- */
-
- #include <string.h>
-
- char *xstrtok(XSTRTOK *xinfo)
- {
- char *scan;
- char *tok;
- char qchar = 0;
- const char *dscan;
-
- /* figure out what stage we are at */
- if (xinfo->str2parse == NULL && xinfo->scanpoint == NULL)
- return(NULL); /* last one went last time */
-
- if (xinfo->str2parse != NULL)
- {
- scan = xinfo->str2parse; /* this is the first time */
- xinfo->str2parse = NULL;
- }
- else
- scan = xinfo->scanpoint; /* we have already started */
-
- /* Skip leading delimiters. */
- for (; *scan; scan++)
- {
- for (dscan = xinfo->delim; *dscan; dscan++)
- if (*scan == *dscan) /* found a delimiter */
- break; /* from inner loop */
-
- if (*dscan == '\0') /* this character not a delimiter */
- break; /* from outer loop */
- }
-
- /* are we finished with the line? */
- if (*scan == '\0')
- {
- xinfo->scanpoint = NULL;
- return(NULL);
- }
-
- /* otherwise we now point to the next token */
- tok = scan;
-
- /* find the end of the token */
- /* three versions for speedup rather than testing within loop */
-
- /* first find empty string such as "" */
- if (xinfo->quote && (*tok == '\"' || *tok == '\'') && tok[0] == tok[1])
- {
- *tok = 0;
- xinfo->scanpoint = tok + 2;
- return(tok);
- }
-
- /* non-empty string respecting quotes */
- if (xinfo->quote) for (; *scan != '\0'; scan++)
- {
- for (dscan = xinfo->delim; *dscan != '\0';) /* increment is in body */
- {
- /* have we found a delimiter? */
- if (*scan == *dscan++)
- {
- xinfo->scanpoint = scan + 1; /* point to next character */
- *scan = '\0'; /* terminate the token */
- return(tok); /* and return it */
- }
-
- /* is it a quote character */
- if (*scan == '\'' || *scan == '\"')
- {
- qchar = *scan; /* search for same close quote */
- strcpy(scan, scan + 1); /* don't return quotes */
-
- while (*scan && *scan != qchar)
- scan++;
-
- strcpy(scan, scan + 1); /* don't return quotes */
- }
- }
- }
- /* normal strtok semantics */
- else for (; *scan != '\0'; scan++)
- {
- for (dscan = xinfo->delim; *dscan != '\0';) /* increment is in body */
- {
- /* have we found a delimiter? */
- if (*scan == *dscan++)
- {
- xinfo->scanpoint = scan + 1; /* point to next character */
- *scan = '\0'; /* terminate the token */
- return(tok); /* and return it */
- }
- }
- }
-
- /* Reached end of string. */
- xinfo->scanpoint = NULL;
- return(tok);
- }
-
- --
- D'Arcy J.M. Cain (darcy@druid.com) |
- D'Arcy Cain Consulting | There's no government
- Toronto, Ontario, Canada | like no government!
- +1 416 424 2871 DoD#0082 |
-