strtok() is shit, as
>>2 said. Use gettok() instead.
/*******************************************************************************
* gettok.c -- an improved strtok(). *
* Copyright (c) 2008, Samuel Fredrickson <kinghajj@gmail.com>; *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions are met: *
* * Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. *
* * 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. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``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 COPYRIGHT HOLDER 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. *
******************************************************************************/
/* strtok() is a neat little function, but it's somewhat ackward to use, and
* it's not thread-safe. this one is thread-safe, and (I think) makes more
* sense.
*/
#include <string.h>
#ifdef _GETTOK_DEMO_
#include <stdio.h>
#include <stdlib.h>
#endif
/**
* @param start A pointer to a string; keeps track of current position in
* original string.
* @param delims Characters that will deliminate tokens.
* @return A pointer to the first found token, or NULL if none found.
*
* gettok() works by taking in a pointer to a string, searching through that
* string for deliminators, then updating that string so that on the next call,
* it will return the next token.
*
* Like strtok(), gettok() modifies the original string by inserting NULs where
* it finds deliminators.
*
* @code
* void foo(char *str)
* {
* char *start = str, *tok;
*
* while((tok = gettok(&start, " ")))
* processToken(tok);
* }
* @endcode
*/
char *gettok(char **start, char *delims)
{
char *token = NULL;
if(start && *start && **start && delims)
// Find the first occurance of a delimeter.
if(*start = strpbrk(token = *start, delims))
// Nullify consecutive delimeters.
while(**start && strchr(delims, **start))
*(*start)++ = '\0';
// if token is NULL, let it pass. if token is not NULL but points to a '\0',
// then the token hasn't really been found, so recurse to find it.
return (!token || *token) ? token : gettok(start, delims);
}
#ifdef _GETTOK_DEMO_
int main()
{
static char s[] = " ;; This is a;,; ;string;with; ;delims.";
static char output[64];
char *start = s, *tok;
while((tok = gettok(&start, " ;,"))) {
printf("tok: \"%s\"\n", tok);
strcat(output, tok);
strcat(output, " ");
}
printf("Output: %s\n", output);
return 0;
}
#endif