parsing a string

Discussion in 'C Programming' started by Stu, Dec 4, 2006.

  1. Stu

    Stu Guest

    Can somebody please tell me the most effient away to parse the date
    YYYYMMDD from the following string.

    char *date_path = "/dira/dirb/dirc/dird/2006/12/04"

    Note: the number of directories before the date can vary.

    Thanks in advance for that respond
    Stu, Dec 4, 2006
    #1
    1. Advertising

  2. Stu said:

    > Can somebody please tell me the most effient away to parse the date
    > YYYYMMDD from the following string.
    >
    > char *date_path = "/dira/dirb/dirc/dird/2006/12/04"
    >
    > Note: the number of directories before the date can vary.


    Look up strrchr.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at the above domain, - www.
    Richard Heathfield, Dec 4, 2006
    #2
    1. Advertising

  3. Stu

    Tom St Denis Guest

    Stu wrote:
    > Can somebody please tell me the most effient away to parse the date
    > YYYYMMDD from the following string.
    >
    > char *date_path = "/dira/dirb/dirc/dird/2006/12/04"
    >
    > Note: the number of directories before the date can vary.
    >
    > Thanks in advance for that respond


    If the date is always at the end, why not work backwards?

    :)

    Tom -- ruining the education system for others since 1998.
    Tom St Denis, Dec 4, 2006
    #3
  4. Stu

    Eric Sosman Guest

    Richard Heathfield wrote:
    > Stu said:
    >
    >> Can somebody please tell me the most effient away to parse the date
    >> YYYYMMDD from the following string.
    >>
    >> char *date_path = "/dira/dirb/dirc/dird/2006/12/04"
    >>
    >> Note: the number of directories before the date can vary.

    >
    > Look up strrchr.


    strrchr() doesn't seem to be the answer here. He doesn't
    need to find the rightmost '/', but the antepenultimate '/'.
    Finding the rightmost does not seem to further his eventual
    goal -- not unless he can modify the string, which he hasn't
    told is is permissible.

    Personally, I'd do it by scanning for '/' characters and
    remembering the three most recently found:

    char *p1 = NULL, *p2 = NULL, *p3 = NULL, *p;
    for (p = the_string; *p != '\0'; ++p) {
    if (*p == '/') {
    p1 = p2;
    p2 = p3;
    p3 = p;
    }
    }
    if (p1 == NULL)
    die_horribly();
    else {
    /* p1 points to the start of "/yyyy/mm/dd" */
    }

    The one-by-one loop could be replaced with strchr():

    char *p1 = NULL, *p2 = NULL, *p3 = NULL, *p = the_string;
    while ((p = strchr(p, '/')) != NULL) {
    p1 = p2;
    p2 = p3;
    p3 = p++;
    }
    if (...)

    --
    Eric Sosman
    lid
    Eric Sosman, Dec 5, 2006
    #4
  5. Stu

    Simon Biber Guest

    Stu wrote:
    > Can somebody please tell me the most effient away to parse the date
    > YYYYMMDD from the following string.
    >
    > char *date_path = "/dira/dirb/dirc/dird/2006/12/04"
    >
    > Note: the number of directories before the date can vary.
    >
    > Thanks in advance for that respond


    I doubt you'll get much more efficient than this.

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

    void get_date(long *year, long *month, long *day, const char *date_path)
    {
    size_t len = strlen(date_path);
    assert(len >= 10 && date_path[len - 6] == '/'
    && date_path[len - 3] == '/');
    *year = strtol(date_path + len - 10, 0, 10);
    *month = strtol(date_path + len - 5, 0, 10);
    *day = strtol(date_path + len - 2, 0, 10);
    }

    int main(void)
    {
    long year, month, day;
    get_date(&year, &month, &day, "/dira/dirb/dirc/dird/2006/12/04");
    printf("%04ld/%02ld/%02ld\n", year, month, day);
    get_date(&year, &month, &day, "1982/09/06");
    printf("%04ld/%02ld/%02ld\n", year, month, day);
    return 0;
    }

    --
    Simon.
    Simon Biber, Dec 5, 2006
    #5
  6. Stu

    santosh Guest

    Stu wrote:
    > Can somebody please tell me the most effient away to parse the date
    > YYYYMMDD from the following string.
    >
    > char *date_path = "/dira/dirb/dirc/dird/2006/12/04"
    >
    > Note: the number of directories before the date can vary.
    >
    > Thanks in advance for that respond


    If date will always be of the form YYYY/MM/DD and you know the length
    of the string, do:
    char *date = (date_path + date_path_length) - 11;

    If you know the string length but the date could be of variable length
    then do:
    char *date = date_path + date_path_length;
    size_t cnt;
    for(cnt = 0; date >= date_path || cnt < 3; date--)
    if(*date == '/') cnt++;

    If string length is unknown then a straightforward scan from the
    beginning using isdigit() might be the best option.
    santosh, Dec 5, 2006
    #6
  7. Eric Sosman said:

    > Richard Heathfield wrote:
    >> Stu said:
    >>
    >>> Can somebody please tell me the most effient away to parse the date
    >>> YYYYMMDD from the following string.
    >>>
    >>> char *date_path = "/dira/dirb/dirc/dird/2006/12/04"
    >>>
    >>> Note: the number of directories before the date can vary.

    >>
    >> Look up strrchr.

    >
    > strrchr() doesn't seem to be the answer here. He doesn't
    > need to find the rightmost '/', but the antepenultimate '/'.
    > Finding the rightmost does not seem to further his eventual
    > goal -- not unless he can modify the string, which he hasn't
    > told is is permissible.


    On reflection, you're right. I suppose I'm so used to thinking of strchr
    strchr strchr to find the third foo in the bar, and so used to thinking of
    strrchr as the "opposite" of strchr, that this was kind of a mistake
    waiting to happen. Still, it would have got him a third the way there!

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at the above domain, - www.
    Richard Heathfield, Dec 5, 2006
    #7
  8. Stu

    Simon Biber Guest

    Eric Sosman wrote:
    > Richard Heathfield wrote:
    >> Stu said:
    >>
    >>> Can somebody please tell me the most effient away to parse the date
    >>> YYYYMMDD from the following string.
    >>>
    >>> char *date_path = "/dira/dirb/dirc/dird/2006/12/04"
    >>>
    >>> Note: the number of directories before the date can vary.

    >>
    >> Look up strrchr.

    >
    > strrchr() doesn't seem to be the answer here. He doesn't
    > need to find the rightmost '/', but the antepenultimate '/'.
    > Finding the rightmost does not seem to further his eventual
    > goal -- not unless he can modify the string, which he hasn't
    > told is is permissible.


    In fact from his code:
    char *date_path = "/dira/dirb/dirc/dird/2006/12/04"
    ; it's pretty clear that it is not permissible to modify the string.

    While thinking about a solution I first thought about strrchr, then
    realised it didn't help for finding the second-to-last or third-to-last.

    But if the format is fixed at YYYY/MM/DD then all you need to do is find
    the length of the string and subtract 10 from that.

    --
    Simon.
    Simon Biber, Dec 5, 2006
    #8
  9. Stu

    CBFalconer Guest

    Simon Biber wrote:
    >>> Stu said:
    >>>
    >>>> Can somebody please tell me the most effient away to parse the
    >>>> date YYYYMMDD from the following string.
    >>>>
    >>>> char *date_path = "/dira/dirb/dirc/dird/2006/12/04"
    >>>>

    .... snip ...
    >
    > In fact from his code:
    > char *date_path = "/dira/dirb/dirc/dird/2006/12/04"
    > ; it's pretty clear that it is not permissible to modify the string.
    >
    > While thinking about a solution I first thought about strrchr, then
    > realised it didn't help for finding the second-to-last or third-to-last.
    >
    > But if the format is fixed at YYYY/MM/DD then all you need to do is
    > find the length of the string and subtract 10 from that.


    It that is really the case he just needs to divide the definition
    up into:

    char *date_hdr = "/dira/dirb/dirc/dird/";
    char *date_id = "2006/12/04";

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>
    CBFalconer, Dec 5, 2006
    #9
  10. Simon Biber <> writes:
    > Stu wrote:
    >> Can somebody please tell me the most effient away to parse the date
    >> YYYYMMDD from the following string.
    >> char *date_path = "/dira/dirb/dirc/dird/2006/12/04"
    >> Note: the number of directories before the date can vary.
    >> Thanks in advance for that respond

    >
    > I doubt you'll get much more efficient than this.
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    > #include <string.h>
    > #include <assert.h>
    >
    > void get_date(long *year, long *month, long *day, const char *date_path)
    > {
    > size_t len = strlen(date_path);
    > assert(len >= 10 && date_path[len - 6] == '/'
    > && date_path[len - 3] == '/');
    > *year = strtol(date_path + len - 10, 0, 10);
    > *month = strtol(date_path + len - 5, 0, 10);
    > *day = strtol(date_path + len - 2, 0, 10);
    > }
    >
    > int main(void)
    > {
    > long year, month, day;
    > get_date(&year, &month, &day, "/dira/dirb/dirc/dird/2006/12/04");
    > printf("%04ld/%02ld/%02ld\n", year, month, day);
    > get_date(&year, &month, &day, "1982/09/06");
    > printf("%04ld/%02ld/%02ld\n", year, month, day);
    > return 0;
    > }


    In real life, of course, you wouldn't want to use assert(). This
    code, as written, doesn't give the caller any opportunity to handle
    errors.

    Probably the best approach is for get_date to return an error indication.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Dec 5, 2006
    #10
  11. Stu

    Joe Wright Guest

    Simon Biber wrote:
    > Stu wrote:
    >> Can somebody please tell me the most effient away to parse the date
    >> YYYYMMDD from the following string.
    >>
    >> char *date_path = "/dira/dirb/dirc/dird/2006/12/04"
    >>
    >> Note: the number of directories before the date can vary.
    >>
    >> Thanks in advance for that respond

    >
    > I doubt you'll get much more efficient than this.
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    > #include <string.h>
    > #include <assert.h>
    >
    > void get_date(long *year, long *month, long *day, const char *date_path)
    > {
    > size_t len = strlen(date_path);
    > assert(len >= 10 && date_path[len - 6] == '/'
    > && date_path[len - 3] == '/');
    > *year = strtol(date_path + len - 10, 0, 10);
    > *month = strtol(date_path + len - 5, 0, 10);
    > *day = strtol(date_path + len - 2, 0, 10);
    > }
    >
    > int main(void)
    > {
    > long year, month, day;
    > get_date(&year, &month, &day, "/dira/dirb/dirc/dird/2006/12/04");
    > printf("%04ld/%02ld/%02ld\n", year, month, day);
    > get_date(&year, &month, &day, "1982/09/06");
    > printf("%04ld/%02ld/%02ld\n", year, month, day);
    > return 0;
    > }
    >

    Maybe..

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

    int main(void) {
    char *date_path = "/dira/dirb/dirc/dird/2006/12/04";
    char *date = date_path + (strlen(date_path) - 10);
    puts(date_path);
    puts(date);
    return 0;
    }

    --
    Joe Wright
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
    Joe Wright, Dec 6, 2006
    #11
    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. GIMME
    Replies:
    2
    Views:
    864
    GIMME
    Feb 11, 2004
  2. Naren
    Replies:
    0
    Views:
    570
    Naren
    May 11, 2004
  3. Christopher Diggins
    Replies:
    0
    Views:
    597
    Christopher Diggins
    Jul 9, 2007
  4. Christopher Diggins
    Replies:
    0
    Views:
    422
    Christopher Diggins
    Jul 9, 2007
  5. John Levine
    Replies:
    0
    Views:
    715
    John Levine
    Feb 2, 2012
Loading...

Share This Page