You have no reason to think that it's better but ok. Regardless, you're not supposed to bump threads more than two weeks old, it's against the rules. We're approaching the end of May.
Printable View
You have no reason to think that it's better but ok. Regardless, you're not supposed to bump threads more than two weeks old, it's against the rules. We're approaching the end of May.
My vast apologies for the error. The thread was rather near the top of the list while looking at the New Posts. Quickly scanning the date of the post prior to mine shows a date of 4/20--I must have had a thinking error and interpreted it as 5/20, or yesterday.
As to your first comment: yes I do.
The only thing your solution does differently than strtok is that it stores the result in a different place. That solves only one of strtok's problems, and not very well. If the space passed is too short, your function simply barfs, which to me is not a solution at all. I can't like that decision.
One of the most legitimate concerns with strtok is that it screws up empty tokens.
-> "test"Code:int main ( void )
{
const char * parseme = "test;test2;;test3\n";
char part[BUFSIZ];
const char * result = NULL;
while ( ( result = better_strtok( parseme, ";\n", part, sizeof part ) ) != NULL ) {
parseme = result;
printf( "-> \"%s\"\n", part );
}
return 0;
}
-> "test2"
-> "test3"
That's a pretty bad result too. When I can copy the string and pass the copy to strtok with the same results, I would prefer that to your broken function.
I trust that despite rules to the contrary that it's OK to post here.
To address your first concern, it's a simple matter to malloc the buffer to hold the result. The function result now indicates whether or not an entry was returned rather than a pointer to the memory. This was largely done to be compatible with the version of the code that follows this one.
To address your second concern, which really changes this from being a better strtok to being an entirely different beast, it's a matter of not treating multiple delimiters as a single entity. Potential issues here are what to do if the first character is a deliminter and/or the last character is a delimiter: do these genuinely delimit entries or are they merely there for completeness? The code below treats a delimiter as actually having an entry of interest on either side of it.Code:int better_strtok(char **str, char *delim, char **result) {
char *start = *str;
while (*start && strchr(delim, *start)) start++;
if (*start == '\0') return 0;
char *ptr = start;
while (1) {
if (strchr(delim, *ptr)) {
*result = malloc(ptr - start + 1);
strncpy(*result, start, ptr - start);
(*result)[ptr - start] = '\0';
*str = ptr;
return 1;
}
ptr++;
}
}
int main(void) {
char *str = "test;test2;;test3\n";
char *buf;
char *ptr = str;
while (better_strtok(&ptr, ";\n", &buf)) {
printf("> %s\n", buf);
free(buf);
}
}
> test
> test2
> test3
Code:int better_strtok(char **str, char *delim, char **result) {
char *start = *str;
char *ptr = start;
while (1) {
if (strchr(delim, *ptr)) {
*result = malloc(ptr - start + 1);
strncpy(*result, start, ptr - start);
(*result)[ptr - start] = '\0';
*str = ptr + 1;
return *ptr;
}
ptr++;
}
}
int main(void) {
char *str = "test;test2;;test3\n";
ptr = str;
int result = 1;
while (result) {
result = better_strtok(&ptr, ";\n", &buf);
printf("-> %s\n", buf);
free(buf);
}
}
> test
> test2
>
> test3
>