strtok - determine delimiter at certain position

Discussion in 'C Programming' started by magix, Sep 30, 2006.

  1. magix

    magix Guest

    Dear Guru,

    I have been thinking hard on how to token based on demiliter after certain
    position.
    Example, I have list of possible string below, and the the delimiter is "1"
    with the rules below
    - if the 5th character is "1", then it is delimiter
    elseif the 7th character is "1", then it is delimiter
    else
    this string is not a valid string


    NE341LCBAA35
    NE311LCBAA35
    NE141LCBAA35
    NE31341LCBAA35

    I have code:

    strcpy(szPrefix,strtok(token,"1\n"));
    strcpy(szSuffix,strtok(NULL,"1\n"));

    but only able to detect the 1st occurence of "1", and treat it as delimiter,
    based on the rules above, this is not valid if has string like NE311LCBAA35.

    What I want to achieve is: If I have string NE311LCBAA35, my delimiter will
    be the 5th "1", and my
    szPrefix = "NE31"
    szSuffix = "LCBAA35"

    Could you share with me on how to achieve above rules ?

    Many thanks.

    P/S: this is not school homeworks or anything. I'm a working adult, just my
    personal interest in programming.

    Regards.
     
    magix, Sep 30, 2006
    #1
    1. Advertising

  2. magix

    Ralph Moritz Guest

    "magix" <> writes:

    > I have been thinking hard on how to token based on demiliter after certain
    > position.
    > Example, I have list of possible string below, and the the delimiter is "1"
    > with the rules below
    > - if the 5th character is "1", then it is delimiter
    > elseif the 7th character is "1", then it is delimiter
    > else
    > this string is not a valid string


    For a simple case like this, just copying string segments around is
    probably easier than trying to use strtok(). See my example program
    below. (Error handling omitted for brevity)

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

    int main(int argc, char *argv[])
    {
    enum { MINDP = 4, MAXDP = 6 };
    char *input, *prefix, *suffix;
    size_t pos = 0;
    size_t sl;

    if (argc != 2) {
    fprintf(stderr, "Usage: chop TEXT\n");
    exit(1);
    }

    input = argv[1];
    if (input[MINDP] == '1')
    pos = MINDP;
    else if (input[MAXDP] == '1')
    pos = MAXDP;
    else {
    fprintf(stderr, "Error: invalid string\n");
    exit(1);
    }

    sl = strlen(input) -pos -1;
    prefix = malloc(sizeof(pos +1));
    suffix = malloc(sl +1);
    memcpy(prefix, input, pos);
    memcpy(suffix, input +pos +1, sl);
    prefix[pos] = suffix[sl] = '\0';

    printf("Prefix: %s\nSuffix: %s\n", prefix, suffix);
    return 0;
    }

    --
    Ralph Moritz Ph: +27 846 269 070
    GPG Public Key: http://ralphm.info/public.gpg

    "Faith is believing something you know ain't true."
     
    Ralph Moritz, Sep 30, 2006
    #2
    1. Advertising

  3. magix

    clayne Guest

    magix wrote:
    > Dear Guru,
    >
    > P/S: this is not school homeworks or anything. I'm a working adult, just my
    > personal interest in programming.
    >
    > Regards.


    Yeah anyways, best to avoid strtok(), as it is a handicapped interface,
    atleast in my opinion. For these types of routines, I typically just
    use self-written stuff utilizing standard unix iovec structures
    (although these are not necessarily required).

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

    #ifdef HAVE_UIO /* avoid comp.lang.c warnings */
    #include <sys/uio.h>
    #else
    struct iovec {
    void *iov_base;
    size_t iov_len;
    };
    #endif

    typedef struct iovec iov;

    size_t iovtok(iov *v, size_t vc, const char *q, size_t sz, const char
    *t, size_t tsz)
    {
    const char *p, *r;
    size_t vct, tszt;

    for (vct = 0, p = q, r = q + sz; vct < vc && q < r; q++) {
    for (tszt = tsz; tszt; tszt--)
    if (*q == t[tszt - 1]) break;

    if (tszt == 0) {
    continue;
    } else if (q != p) {
    v[vct].iov_base = (void *)p;
    v[vct].iov_len = q - p;
    vct++;
    }

    p = q + 1;
    }

    if (vct < vc && q != p) {
    v[vct].iov_base = (void *)p;
    v[vct].iov_len = q - p;
    vct++;
    }

    return vct;
    }

    int main(int argc, char **argv)
    {
    char buf[1024];
    size_t tl, c, vc, vct;
    iov *v;

    if (argc <= 2) return -1;
    if ((vc = strtol(argv[1], 0, 10)) <= 0) return -1;
    if ((v = malloc(sizeof(*v) * vc)) == NULL) return -1;

    for (tl = strlen(argv[2]); fgets(buf, sizeof(buf), stdin); ) {
    vct = iovtok(v, vc, buf, strlen(buf) - 1, argv[2], tl);

    fprintf(stderr, "vct == %ld\n", (long)vct);
    for (c = 0; c < vct; c++) {
    fprintf(stderr,
    "v[%ld].iov_len == %ld\n",
    (long)c,
    (long)v[c].iov_len);
    fprintf(stderr,
    "v[%ld].iov_base == \"%.*s\"\n",
    (long)c,
    (int)v[c].iov_len,
    (char *)v[c].iov_base);
    }
    }

    free(v);

    return 0;
    }
    --

    $ gcc -Wall -W -ansi -pedantic -g3 -o memsplt memsplt.c
    $ ./memsplt.exe 10 "1" << EOF
    > NE341LCBAA35
    > NE311LCBAA35
    > NE141LCBAA35
    > NE31341LCBAA35
    > EOF

    vct == 2
    v[0].iov_len == 4
    v[0].iov_base == "NE34"
    v[1].iov_len == 7
    v[1].iov_base == "LCBAA35"
    vct == 2
    v[0].iov_len == 3
    v[0].iov_base == "NE3"
    v[1].iov_len == 7
    v[1].iov_base == "LCBAA35"
    vct == 3
    v[0].iov_len == 2
    v[0].iov_base == "NE"
    v[1].iov_len == 1
    v[1].iov_base == "4"
    v[2].iov_len == 7
    v[2].iov_base == "LCBAA35"
    vct == 3
    v[0].iov_len == 3
    v[0].iov_base == "NE3"
    v[1].iov_len == 2
    v[1].iov_base == "34"
    v[2].iov_len == 7
    v[2].iov_base == "LCBAA35"


    I'm sure you can figure out the appropriate code logic to determine 5
    vs 7, etc.
     
    clayne, Sep 30, 2006
    #3
  4. Groovy hepcat magix was jivin' on Sat, 30 Sep 2006 16:21:31 +0800 in
    comp.lang.c.
    strtok - determine delimiter at certain position's a cool scene! Dig
    it!

    >I have been thinking hard on how to token based on demiliter after certain
    >position.
    >Example, I have list of possible string below, and the the delimiter is "1"
    >with the rules below
    >- if the 5th character is "1", then it is delimiter
    > elseif the 7th character is "1", then it is delimiter
    > else
    > this string is not a valid string


    That's incredibly simple.

    if('1' == yer_string[4])
    {
    /* Delimiter is 5th character. */
    }
    else if('1' == yer_string[6])
    {
    /* Delimiter is 7th character. */
    }
    else
    {
    /* Invalid. */
    }

    --

    Dig the even newer still, yet more improved, sig!

    http://alphalink.com.au/~phaywood/
    "Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
    I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
     
    Peter Shaggy Haywood, Oct 2, 2006
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    0
    Views:
    661
  2. David Hirschfield
    Replies:
    3
    Views:
    3,290
    Thomas Guettler
    Feb 3, 2006
  3. Lars =?iso-8859-15?Q?Gust=E4bel?=

    Re: Best way to determine if a certain PID is still running

    Lars =?iso-8859-15?Q?Gust=E4bel?=, Feb 3, 2006, in forum: Python
    Replies:
    2
    Views:
    451
    MrJean1
    Feb 4, 2006
  4. Replies:
    2
    Views:
    529
    bruce barker
    Mar 25, 2008
  5. SAN CAZIANO
    Replies:
    8
    Views:
    179
    Dr John Stockton
    Oct 15, 2004
Loading...

Share This Page