Name:
Anonymous
2010-02-16 13:01
Hello /prog/
Could anyone help me with using the C function strtok and strtok_r?
I've read the man pages and it doesn't provide much help. Try compiling this code example gotten from the man pages:
http://pastebin.com/d11d44ccf
Name:
>>2
2010-02-16 18:11
Here's a "MADNESS LIES HERE" version I wrote when I was bored a year ago:
toknobj.h:
#ifndef _TOKNOBJ_H_
#define _TOKNOBJ_H_
#define OOPINVOKEBASE(obj,type,method) ((C##type##VTable*)(##obj->VTable))->##method(##obj)
#define OOPINVOKEBASEVAR(obj,type,method) ((C##type##VTable*)(##obj->VTable))->##method(##obj,##args)
#define OOPDESTRUCT(obj,type) ((C##type##VTable*)(##obj->VTable))->Destroy##type(##obj);obj=NULL;
typedef struct _TokenObject
{
const void *VTable;
char *separators; // public read-only
char *string; // public mutable
char *current; // pointer to current token in string, private mutable
char *last; // pointer to end-of-string, private read-only
} TokenObject;
void DestroyTokenObject(TokenObject *to);
char *GetToken(TokenObject *to);
TokenObject *CreateTokenObject(char *s, char *seps);
typedef struct _CTokenObjectVTable
{
void ( * DestroyTokenObject)(TokenObject*) ;
char* ( * GetToken)(TokenObject*);
} CTokenObjectVTable;
#endif
toknobj.c:
#include <stdlib.h>
#include "toknobj.h"
const CTokenObjectVTable TokenObjectVTable = { DestroyTokenObject, GetToken };
TokenObject *CreateTokenObject(char *s, char *seps)
{
TokenObject *to;
to = (TokenObject*)malloc(sizeof(TokenObject));
to->separators = (char*)strdup(seps);
to->string = (char*)strdup(s);
to->current = to->string;
to->last = (to->string)+strlen(s);
to->VTable = &TokenObjectVTable;
return to;
}
void DestroyTokenObject(TokenObject *to)
{
free(to->separators);
free(to->string);
free(to);
}
char *GetToken(TokenObject *to)
{
char *s;
char *end;
char *last;
char *seps;
s = to->current;
seps = to->separators;
last = to->last;
if (last <= s ) return NULL;
for(;*s&&strrchr(seps,*s);s++); // skip separators at the beginning of the token
if (last <= s ) return NULL;
for(end=s;*end&&!strrchr(seps,*end);end++);
if(*end) *end=0;
end++;
to->current = end;
return s;
}
// Usage is like this (copy pasted from some real code I wrote, I'm too lazy to write a real example):
char *GetMkvSplitString(char *cutlist, int *splitcount, FRAMERATE *fr)
{
char *tok;
char *splits;
int parity = 0;
TokenObject *to = CreateTokenObject(cutlist,",");
splits = calloc(1,1);
while (tok = OOPINVOKEBASE(to,TokenObject,GetToken))
{
int frame = atoi(tok)+parity;
if (frame)
{
ReallocStrCat(&splits,GetTimeStrFromFrames(frame,fr));
ReallocStrCat(&splits,",");
(*splitcount)++;
}
parity = parity?0:1;
}
OOPDESTRUCT(to,TokenObject);
splits[strlen(splits)-1]=0; // clear last ,
return splits;
}
// Irrelevant, but in case you're wondering, inn util.c:
char *ReallocStrCat( char *dst[], char src[] ) // outputs new pointer to *dst
{
char *newstr;
newstr = malloc(strlen(*dst)+strlen(src)+1);
strcpy(newstr,*dst);
strcat(newstr,src);
free(*dst);
*dst = newstr;
return newstr;
}