. / * * Copyright (c) 1988 Regents of the University of California * All rights reserved * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met:. * 1 . Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and . / or other materials provided with the distribution * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors * 4.. Neither the name of the university nor the name of its controls * May be used to endorse or promote products derived from this software * without specific prio r written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS `` AS IS '' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE dISCLAIMED IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES;. LOSS OF USE, DATA Or profits;
OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * Such Damage. * / # Include
Char * _defun (STRTOK_R, (S, Delim, Lasts), Register Char * S _and register const char * delim _and char ** lasts) {register char * spanp; register int C, sc; char * TOK
IF (s == NULL && (S = * lasts) == null) return (null);
/ * * SKIP (SPAN) Leading Delimiters (S = STRSPN (S, Delim), Sort of). * / Cont: C = * S ; for (spanp = (char *) Delim; (sc = * spanp )! = 0;) {IF (c == sc) goto last
IF (c == 0) {/ * no non-delimiter character; return;} tok = s - 1;
/ * 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 (;;) { C = * s ; spanp = (char *) Delim; do {if ((sc = * spanp ) == c) {if (c == 0) s = null; else s [-1] = 0; * Lasts = S; return (tok);}} while (sc! = 0);} / * notreached * /}
The above is LIBC / STRING / STRTOK_R.C source code actually STRTOK's original code is
#undef __strict_ansi __ # include
#ifndef _reent_only
Char * _defun (STRTOK, S, DELIM), Register Char * S _and register const char * delim) {Return STRTOK_R (S, Delim, & (_ Reent -> _ new._reet._strtok_last);} # ENDIF
Or call the above STRTOK_R
Some Microsoft's specific implementation
CHAR * __CDECL STRTOK (CHAR * STRING, Const Char * Control) {Unsigned Char * Str; Const Unsigned Char * Ctrl = Control; Unsigned Char Map [32]; int count
#ifdef _mt _ptiddata PTD = _GetPTD (); # else / * _mt * / static char * nextoken; #ENDIF / * _MT * /
/ * CLEAR control map * / for (count = 0; count <32; count ) map [count] = 0;
/ * SET BITS in Delimiter Table * / DO {MAP [* Ctrl >> 3] | = (1 << (* Ctrl & 7));} While (* Ctrl );
/ * Initialize str. If String is null, set str to the Saved * Pointer (IE, Continue Breaking tokens out of the string * from the last start "* / if (string) str = string; else # ifdef _mt str = PTD -> _ token; #ELSE / * _MT * / STR = nextoken; #ENDIF / * _MT * /
/ * Find Beginning of token (Skip over LEADING DELIMITERS). Note That * there is no token iff this loop sets str to point to the terminal * Null (* str == '/ 0') * / while ((map [* STR >> 3] & (1 << (* STR & 7))) && * STR) STR ;
String = STR;
/ * Find the end of the token. If it is not the token. IT is not the end of the string, * put a null there. * / For (; * str; str ) IF (Map [* STR >> 3] & (1 << (* STR & 7))) {* STR = '/ 0'; Break;}
/ * Update nextoken (or the corresponding field in the per-thread data * structure * / # ifdef _mt PTD -> _ token = Str; #ELSE / * _MT * / nextoken = str; #ENDIF / * _MT * / / * DETERMINE IF a token has begn. * / if (String == Str) Return Null; Else Return String;} In STRTOK, the second parameter is a list of separators, if it is "abcd", then, 'a', ' B ',' C ',' D ', "AB", "BC", ..., "ABC", ... "abcd", etc., will be separated as a lexical separator!