1

I'd like to know how to use strtok to find values between double brackets, so is that possible to use strtok(mystr, "[]") or no? thanks.

user3464495
  • 39
  • 1
  • 8
  • 1
    Find the first bracket `strtok(data, "[")` then the second `strtok(NULL, "]")`; but you really shouldn't be using `strtok()` for parsing a string. – pmg Mar 31 '14 at 20:08
  • I like to do it with strtok – user3464495 Mar 31 '14 at 20:16
  • @user3464495: depending on the application you can walk the string char-by-char until you find what you want and copy that to another string. Or use `strchr()` to find the interesting markers directly, or try regular expressions – pmg Mar 31 '14 at 20:16
  • 3
    I don't think anyone *likes* parsing with `strtok`. Well, maybe masochists. – jamesdlin Mar 31 '14 at 20:33

2 Answers2

3

As per your comment, asking about what else you should be using, my offer would be to use scanf with scansets %[...], in the following way:

char inside[100];
if ( scanf( "%*[^[][%99[^]]", inside ) == 1 ) {
    ...
}

I know, it could possibly look all gibberish as it is if you are not familiar with scansets, so let me explain it briefly:

Scanset %[...] is just another type of type-specifier, like "%s" and "%d" and so on. It is really similar to "%s", except that it is flexible. By specifying characters inside [...], that doesn't start with a caret ^, those characters will be the only ones that'll be read. In other words, anything else than the specified terminates reading.

When you start off with a caret ^ effect is inversed, the first encounter of the specified characters terminates the scanset reading.

An asterisk * right after the percent sign %, means "Hey, I want you to find these values, but I don't want you to store them into anything, I want them to be discarded."

So, the format string above tells the scanf to;

  • read and discard until the first '[', with the "%*[^[] part
  • read and discard the '[' character afterwards with the "[" part
  • read and store the string until the next ']' character, with maximum length 99 (taking terminating null into consideration), with the "%99[^]]" part

For scanset examples, you may check the following link: https://stackoverflow.com/a/22722090/2736228

Community
  • 1
  • 1
Utkan Gezer
  • 3,009
  • 2
  • 16
  • 29
1

You may use strtok as described in the following example:

int main ()
{
    char str[] ="[x][y] [z]"; // sample string

    // make a copy of the original string to work on
    char *wrk;
    wrk = malloc(strlen(str)+1);
    strcpy(wrk, str);

    // we need a copy of the pointer wrk
    // to be used as parameter for strtok
    char *wrk2;
    wrk2 = wrk;

    // this will hold the pointer to the string returned from strtok
    char * pch;

    while(true)
    {
        pch = strtok(wrk2, "[]");
        if( !pch ) break;
        wrk2 = NULL; // subsequent calls to strtok require wrk2 to be NULL

        // the value is good only if preceeded by an open bracket
        // because strtok retrieve also strings between ] and [
        if(pch>wrk && str[pch-wrk-1]=='[')
        {
            printf ("%s\n",pch);
        }
    }

    free(wrk);

    return 0;
}

Note that in order to use strtok to accomplish what you asked a copy of the original string have to be generated. Let's call it the working string wrk

strtok(wrk, "[]") will retrieve both good substrings between [ ] and unwanted substrings between ] [.

In order to skip unwanted strings a check is made to see if the returned substring is preceeded by an open bracket [.

The necessity of checking this is the reason why a copy of the original string has to be made: in fact strtok edits (splits) the working string by placing null termination characters. The check is made on the original untouched string.

Using strtok results to be quite complicated and require (at least with the approach I suggested) a copy of the original string.

Also the above code won't handle nested string, for example [[a] b]

For complete reference about strtok I suggest http://www.cplusplus.com/reference/cstring/strtok/

Paolo
  • 15,233
  • 27
  • 70
  • 91
  • This version fails on "[x] [y] [z]". It fails to show "x". – lurker Mar 31 '14 at 21:09
  • @mbratch: you're right again, thank you. I edited the answer. However now a different approach is taken and copy of the original string is needed. – Paolo Apr 01 '14 at 10:47
  • I believe that finally nails it, except for the nested brackets, as you point out. The lesson is that it isn't as straight-forward solving this problem with `strtok` as one might initially think. :) – lurker Apr 01 '14 at 11:28
  • 1
    @mbratch: I agree, it's not straight-forward at all. And the code is quite ugly too. I would never follow that approach in a program of mine. But that's what the OP asked for... :) – Paolo Apr 01 '14 at 14:51