#include #include /* ** -------------------------------------------------------------------------- ** ** tokenizeEX ** ** Returns a 'const char *' pointing to the next token or NULL ** if no more tokens were found. ** ** theString - string to be tokenized ** ** stringLength - length of 'theString' ** ** delimiters - the separator characters ** ** pOffset - pointer to the current offset (0, 1, 2, ...) within ** 'theString', should be set to 0 before the first ** call to this function and will from then onward ** but updated automatically. ** ** pLength - the length of the token returned ** ** -------------------------------------------------------------------------- */ static const char *tokenizeEX( const char *theString, int stringLength, const char *delimiters, int *pOffset, int *pTokenSize ) { const char *ptr = NULL; if(theString && delimiters && *pOffset < stringLength) { int i = *pOffset; while(i < stringLength && strchr(delimiters, theString[i])) i++; if(i < stringLength) { int j = i + 1; while(j < stringLength) { if(strchr(delimiters, theString[j])) break; j ++; } *pOffset = j; *pTokenSize = (j - i); ptr = theString + i; } } return(ptr); } /* ** -------------------------------------------------------------------------- ** ** tokenize ** ** Returns a 'const char *' pointing to the next token or NULL ** if no more tokens were found. ** ** theString - string to be tokenized ** ** delimiters - the separator characters ** ** pOffset - pointer to the current offset (0, 1, 2, ...) within ** 'theString', should be set to 0 before the first ** call to this function and will from then onward ** will be updated automatically ** ** pLength - the length of the token returned ** ** -------------------------------------------------------------------------- */ static const char *tokenize( const char *theString, const char *delimiters, int *pOffset, int *pTokenSize ) { return( tokenizeEX( theString, strlen(theString), delimiters, pOffset, pTokenSize ) ); } /****************** * exampleOne ******************/ static void exampleOne() { const char *theString = "2, 3, 5, 7, 11, 13, 17, 19, 23, 29"; const char *token = NULL; int offset = 0; int length = 0; printf("exampleOne: [%s]\n", theString); while((token = tokenize(theString, ", ", &offset, &length)) != NULL) printf("[%.*s]\n", length, token); printf("\n"); } /****************** * exampleTwo ******************/ static void exampleTwo() { const char *theString = "127.0.0.1 4.3.2.1 100.200.300.400"; const char *tokenOuter = NULL; int offsetOuter = 0; int lengthOuter = 0; printf("exampleTwo: [%s]\n", theString); while((tokenOuter = tokenize(theString, " ", &offsetOuter, &lengthOuter)) != NULL) { const char *tokenInner = NULL; int offsetInner = 0; int lengthInner = 0; printf("[%.*s]\n", lengthOuter, tokenOuter); /* -- Because 'tokenOuter' is not null terminated, we must supply its length manually and use tokenizeEX -- */ while((tokenInner = tokenizeEX(tokenOuter, lengthOuter, ".", &offsetInner, &lengthInner)) != NULL) printf(" [%.*s]\n", lengthInner, tokenInner); } printf("\n"); } /****************** * exampleThree ******************/ static void exampleThree() { const char *theString = "a, b, 'c, d, e', f, 'g, h, i, j, k'"; const char *token = NULL; int offset = 0; int length = 0; printf("exampleThree: [%s]\n", theString); while((token = tokenize(theString, "'", &offset, &length)) != NULL) { char buffer[255] = { 0 }; int offsetInner = 0; int lengthInner = 0; /* -- By copying to 'buffer', our string will be null terminated so we don't need to use tokenizeEX, we can use tokenize -- */ snprintf(buffer, sizeof(buffer), "%.*s", length, token); printf("[%s]\n", buffer); while((token = tokenize(buffer, ", ", &offsetInner, &lengthInner)) != NULL) printf(" [%.*s]\n", lengthInner, token); } } /****************** * main ******************/ int main() { exampleOne(); exampleTwo(); exampleThree(); return(0); }