C/C++

NAVIGATION
CATEGORIES
REFERRENCE
LINKS
  • help getting substring

    8 answers - 861 bytes - related search similar search Add To My Delicious Add To My Stumble Upon Add To My Google Mark Add To My Facebook Add To My Digg Add To My Reddit

    Hi there,
    I need a program to extract a substring from the following pattern
    xxxx<XXXXX>xxxx
    therer, x and X are any character and the string between < and is
    what I need. I use the following program to extract the substring, but
    something wrong
    char* deangle(const char* lpStr)
    {
    char *lpBuf = (char *)lpStr;
    char *p = strchr( lpBuf, '<' ) + 1;
    if (!p) return NULL;
    char *q = strchr( lpBuf, '>' );
    if (!q) return NULL;
    *q = '\0'; /* to make sure no extra characters at the end of the
    substring
    memcpy( lpBuf, p, q-p );
    return lpBuf;
    }
    apply the function to some string like xxxx<http://www.abc.com>xxxx
    what I get is "http://www.abc.comm"
    I am wondering where is the double m come?
    Thanks in advance
  • No.1 | | 580 bytes | |

    Hello,

    See comments inline (not tested):

    gmclee@21cn.com wrote:
    char* deangle(const char* lpStr)
    {
    char *lpBuf = (char *)lpStr;
    char *p = strchr( lpBuf, '<' ) + 1;
    if (!p) return NULL;

    Compare with null AFTER addition of 1?

    char *q = strchr( lpBuf, '>' );
    if (!q) return NULL;
    *q = '\0'; /* to make sure no extra characters at the end of the
    substring

    Modify const char * ?

    memcpy( lpBuf, p, q-p );

    q-p+1?

    return lpBuf;
    }

    Kidn regards.

  • No.2 | | 1011 bytes | |

    gmclee@21cn.com wrote:

    Hi there,
    I need a program to extract a substring from the following pattern

    xxxx<XXXXX>xxxx

    therer, x and X are any character and the string between < and is
    what I need. I use the following program to extract the substring, but
    something wrong

    char* deangle(const char* lpStr)
    {
    char *lpBuf = (char *)lpStr;
    char *p = strchr( lpBuf, '<' ) + 1;
    if (!p) return NULL;
    char *q = strchr( lpBuf, '>' );
    if (!q) return NULL;
    *q = '\0'; /* to make sure no extra characters at the end of the
    substring
    memcpy( lpBuf, p, q-p );
    Better to use memmove since p points inside lpBuf.
    You missed the terminating nul.use memmove( lpBuf, p, q-p+1 );
    return lpBuf;
    }

    apply the function to some string like xxxx<http://www.abc.com>xxxx

    what I get is "http://www.abc.comm"

    I am wondering where is the double m come?

    Thanks in advance

  • No.3 | | 575 bytes | |

    gmclee@21cn.com wrote:

    char* deangle(const char* lpStr)
    {
    char *lpBuf = (char *)lpStr;

    Careful. You just cast away the const.

    char *p = strchr( lpBuf, '<' ) + 1;
    if (!p) return NULL;
    char *q = strchr( lpBuf, '>' );
    if (!q) return NULL;
    *q = '\0';

    You just wrote to read-only memory. Clearly,
    you didn't mean to declare lpStr as const.

    memcpy( lpBuf, p, q-p );

    Ackk! You are really blowing away lpStr!! Is
    this intentional?

    return lpBuf;
    }

  • No.4 | | 1317 bytes | |

    gmclee@21cn.com wrote:
    Hi there,
    I need a program to extract a substring from the following pattern

    xxxx<XXXXX>xxxx

    therer, x and X are any character and the string between < and is
    what I need. I use the following program to extract the substring, but
    something wrong

    char* deangle(const char* lpStr)
    {
    char *lpBuf = (char *)lpStr;
    char *p = strchr( lpBuf, '<' ) + 1;
    if (!p) return NULL;
    char *q = strchr( lpBuf, '>' );
    if (!q) return NULL;
    *q = '\0'; /* to make sure no extra characters at the end of the
    substring
    memcpy( lpBuf, p, q-p );
    return lpBuf;
    }

    apply the function to some string like xxxx<http://www.abc.com>xxxx

    what I get is "http://www.abc.comm"

    I am wondering where is the double m come?

    Thanks in advance

    I would do something like

    void get_bracketed_string(const char s[], char result[])
    {
    char *langle, *rangle;

    langle = strchr(s, '<');
    rangle = strchr(s, '>');
    if ((langle == NULL) || (rangle == NULL) || (langle rangle)) {
    result = "";
    } else {
    strncpy(result, langle + 1, rangle - langle - 1);
    result[rangle - langle - 1] = '\0';
    }
    }

    August
  • No.5 | | 798 bytes | |

    August Karlstrom wrote:
    I would do something like

    void get_bracketed_string(const char s[], char result[])
    {
    char *langle, *rangle;

    I'd keep these as const char * to reinforce that you still can't modify
    the contents even though strchr has returned a non-const pointer.

    langle = strchr(s, '<');
    rangle = strchr(s, '>');
    if ((langle == NULL) || (rangle == NULL) || (langle rangle)) {
    result = "";

    There's no point modifying the parameter! The caller won't notice any
    change. You'd better change it to this:
    result[0] = '\0';

    } else {
    strncpy(result, langle + 1, rangle - langle - 1);
    result[rangle - langle - 1] = '\0';
    }
    }
    --
    August
  • No.6 | | 57 bytes | |

    Thank you all of you. I've got it
  • No.7 | | 1808 bytes | |

    gmclee@21cn.com wrote:
    Hi there,
    I need a program to extract a substring from the following pattern

    xxxx<XXXXX>xxxx

    therer, x and X are any character and the string between < and is
    what I need. I use the following program to extract the substring, but
    something wrong

    char* deangle(const char* lpStr)
    {
    char *lpBuf = (char *)lpStr;
    char *p = strchr( lpBuf, '<' ) + 1;
    if (!p) return NULL;
    char *q = strchr( lpBuf, '>' );
    if (!q) return NULL;
    *q = '\0'; /* to make sure no extra characters at the end of the
    substring
    memcpy( lpBuf, p, q-p );
    return lpBuf;
    }

    In addition to the various points made so far you also have a big
    logic error. What does deangle do when passed a string of the form
    "xxx>XXXX<xxx"?

    So as not to be accused of being too negative, I would propose:

    char *deangle(char *str)
    {
    char *open = strchr(str, '<');
    if (!open)
    return NULL;
    char *close = strchr(open + 1, '>');
    if (!close)
    return NULL;
    int sublen = (close - open) - 1; /* will be >= 0 */
    memmove(str, open + 1, sublen);
    str[sublen] = '\0';
    return str;
    }

    or, in older C, and in the single-entry-exit style:

    char *deangle(char *str)
    {
    char *close;
    char *open = strchr(str, '<');
    if (open && (close = strchr(open + 1, '>'))) {
    int sublen = (close - open) - 1; /* will be >= 0 */
    memmove(str, open + 1, sublen);
    str[sublen] = '\0';
    }
    else str = NULL;
    return str;
    }

    but I would argue against the idea of returning a pointer to the same
    (clobbered) data. What if the string has two <parts and you
    later want both?
  • No.8 | | 1285 bytes | |

    Simon Biber wrote:
    August Karlstrom wrote:
    >I would do something like
    >>

    >void get_bracketed_string(const char s[], char result[])
    >{
    >char *langle, *rangle;
    >

    I'd keep these as const char * to reinforce that you still can't modify
    the contents even though strchr has returned a non-const pointer.

    K.

    >langle = strchr(s, '<');
    >rangle = strchr(s, '>');
    >if ((langle == NULL) || (rangle == NULL) || (langle rangle)) {
    >result = "";
    >

    There's no point modifying the parameter! The caller won't notice any
    change. You'd better change it to this:
    result[0] = '\0';

    Yes of course, thanks.

    Now we have:

    void get_bracketed_string(const char s[], char result[])
    {
    const char *langle, *rangle;

    langle = strchr(s, '<');
    rangle = strchr(s, '>');
    if ((langle == NULL) || (rangle == NULL) || (langle rangle)) {
    result[0] = '\0';
    } else {
    strncpy(result, langle + 1, rangle - langle - 1);
    result[rangle - langle - 1] = '\0';
    }
    }

    August

Re: help getting substring


max 4000 letters.
Your nickname that display:
In order to stop the spam: 7 + 6 =
QUESTION ON "C/C++"

EMSDN.COM