0

I'm trying to parse a text string (char *) using strsep(), the problem is that the separators must be used by order ex.: the first token by ',' the 2nd by ':'...

sep = " ,:-,.!.";
tofree = string;

while (token = strsep(&string, " ,:-,.!."))            
{
  validate(token);
}

free(tofree);

The strsep() separates by any of the sep chars in the string. After reading strsep() and strtok_r() man, still gone nowere. Is there a way to do this in a while cycle? Any ideas would be helpful. Thaks

Mat
  • 202,337
  • 40
  • 393
  • 406

2 Answers2

0

You can strtok() with an array of delimiters in a loop.

strsep() and strtok_r() are not ISO/IEC C11 Standard defined functions.

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

int separate(const char *data, const char **delims) {
  char *dat = malloc(strlen(data) + 1);
  char *p;
  size_t delimindex = 0;

  if (!dat) return 1;
  strcpy(dat, data);
  p = strtok(dat, delims[delimindex++]);
  while (delims[delimindex] && p) {
    printf("%s\n", p);
    p = strtok(NULL, delims[delimindex++]);
  }
  free(dat);
  return 0;
}

int main(void) {
  const char *delims[] = {" ", ",", ":", "-", ",", ".", "!", ".", NULL};
  const char *test1 = "aaa bbb,ccc:ddd-eee,fff.ggg!hhh.iii";
  const char *test2 = "foobar";
  separate(test1, delims);
  separate(test2, delims);
  return 0;
}
pmg
  • 106,608
  • 13
  • 126
  • 198
  • 1
    "`strtok_r()` is not standard" is not true as-is. It may not be part of C89 (99?) but [it's certainly in POSIX](http://pubs.opengroup.org/onlinepubs/009604599/functions/strtok.html). –  Mar 09 '13 at 12:00
  • I meant [the ISO/IEC C11 Standard](http://www.open-std.org/JTC1/sc22/wg14/www/docs/n1570.pdf). – pmg Mar 09 '13 at 12:14
0

You can put the separators in an array and use them one by one:

const char *seps[] = {
    ",",
    ":",
    "-",
    ",",
    ".",
    "!",
    "."
};

char str[] = "Foo,Bar:Baz-Quirk,Whatever.Foo!Bar.Baz";

char *end;
char *result;

int i;
for (i = 0; i < sizeof(seps) / sizeof(*seps); i++) {
    result = strtok_r(i ? NULL : str, seps[i], &end);
    // do stuff with `result`
    printf("%s\n", result);
}
  • I like `sizeof (object) / sizeof (*object)` (without redundant parenthesis) better than yours `sizeof (object) / sizeof ()`. – pmg Mar 09 '13 at 12:21
  • @pmg Me too, but I thought for some reason we couldn't do that. Fixed now. –  Mar 09 '13 at 12:35