help getting substring

G

gmclee

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
 
T

tmp123

Hello,

See comments inline (not tested):

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.
 
M

manoj1978

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 );
 
B

Bill Pursell

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';

Oooohh... 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?
 
A

August Karlstrom

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
 
S

Simon Biber

August said:
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
 
B

Ben Bacarisse

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?
 
A

August Karlstrom

Simon said:
August said:
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.
OK.
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top