views:

178

answers:

4

I have the string: "foo$bar@baz"

I'm looking to write a C program which will extra all three sub-strings ("foo", "bar" and "baz") and put each into it's own string.

P.S. Don't worry, this is not homework.

+10  A: 

What you are looking for is strtok. It allows for you to set the delimiters as well.

monksy
As long as the string being tokenized is modifiable. Don't do `strtok("foo$bar@baz","$");`
Steve Jessop
Why is the score 7 where there are 9 upvotes and 1 downvote. I guess someone doesn't like strtok.. weird.
monksy
+1  A: 

if it is not for homework :-) than strtok is not recommended, if you can't use C++ (why?) you should use strtok_r (reentrent version)

Yuval
A: 

Strtok keeps a static buffer when tokenizing that gets overwritten when if called elsewhere with a new non-NULL string, which could break the functionality you're looking for. e.g. interwoven calls with different strings.

Instead, you can use strsep, which is like strtok, but you keep the temporary buffer yourself, in case you need to tokenize multiple strings, e.g. with the interwoven calls with different strings.

In small cases, this problem probably won't arise, but it can in larger projects.

EDIT: this isn't std c, so make sure you have this function before trying to use it. I know for certain that it is available on BSD, and possibly other unix's

EDIT: strsep and strtok_r appear to have the same functionality

+1  A: 

Since this is straight C, it might be fun to revisit how strings are stored and terminated. Since you have one terminating character for each section, you can just make it into a true terminator ('\0') and leave the strings in place:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv) {

char *s1,*s2,*s3, *test = "foo$bar@baz";
char *buf=(char *)malloc(100);
char *p,c;

strcpy(buf, test);

s1 = p = buf;
while(c = *p) {
  if (c == '$') { *p = '\0'; s2 = p+1; }
  if (c == '@') { *p = '\0'; s3 = p+1; }
  p++;
}

printf("s1 = %s\n",s1);
printf("s2 = %s\n",s2);
printf("s3 = %s\n",s3);

}

I wouldn't do this in production code, in this day and age. But way back when, doing one pass on the loop, and one copy for storage, would have been considered a big win.

john personna
Darn, 2 passes if you count the strcpy. A copy-and-set loop is left as an exercise for the reader.
john personna
than don't do a copy first :)
warren