473,386 Members | 1,706 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

removing substring from string

I am little bit confused
Is this a legal way of removing a substring
from a string? What about the second alternative
using strcpy, is it ok even though the source and
dest. strings overlap?

// Remove (first occurence of) sub from src
void func(char *src, char *sub)
{
char *p;
if ((p=strstr(src,sub)) != NULL)
{
memmove(p,p+strlen(sub), strlen(p+strlen(sub))+1);

// alternative
// strcpy(p,p+strlen(sub));
}
}
Nov 14 '05 #1
6 22693
becte wrote:
I am little bit confused
Is this a legal way of removing a substring
from a string? What about the second alternative
using strcpy, is it ok even though the source and
dest. strings overlap?

// Remove (first occurence of) sub from src
void func(char *src, char *sub)
{
char *p;
if ((p=strstr(src,sub)) != NULL)
{
memmove(p,p+strlen(sub), strlen(p+strlen(sub))+1);
Looks all right to me.
// alternative
// strcpy(p,p+strlen(sub));
Undefined behavior if source and destination overlap
(i.e., if strlen(p+strlen(sub)) >= strlen(sub)).
}
}

Nov 14 '05 #2


becte wrote:
I am little bit confused
Is this a legal way of removing a substring
from a string? What about the second alternative
using strcpy, is it ok even though the source and
dest. strings overlap?

// Remove (first occurence of) sub from src
void func(char *src, char *sub)
{
char *p;
if ((p=strstr(src,sub)) != NULL)
{
memmove(p,p+strlen(sub), strlen(p+strlen(sub))+1);

// alternative
// strcpy(p,p+strlen(sub));
}
}


The Standard's Description of function strcpy says
"If copying takes place between objects that
overlap, the behavior is undefined."
p, pointing to an array than includes the string
pointed to by p+strlen(sub), is an overlap.
An implementator is free to implement function strcpy
similiar to this:
char *MyStrCpy(char *s, const char *cs)
{
const char *tmp;
size_t n = strlen(cs);

for(tmp = cs+n; ; tmp--,n--)
{
*(s+n) = *tmp;
if(!n) break;
}
return s;
}
Using this as your strcpy function in the function func
will fail to give the expected result.
The Standard's description of function memmove describes
the behavior is AS IF the characters(number: strlen(p+strlen(sub))
pointed to by p+strlen(sub) are first copied to a seperate
temporary object. Therefore this function would be safe
to use in the code above. There is no overlapping problem.

Of the two, I would stick with function memmove.

--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #3

becte wrote:
I am little bit confused
Is this a legal way of removing a substring
from a string? What about the second alternative
using strcpy, is it ok even though the source and
dest. strings overlap?

// Remove (first occurence of) sub from src
void func(char *src, char *sub)
{
char *p;
if ((p=strstr(src,sub)) != NULL)
{
memmove(p,p+strlen(sub), strlen(p+strlen(sub))+1);

// alternative
// strcpy(p,p+strlen(sub));
}
}


Since the source and destination operands overlap, memmove() is your
safest bet. Don't use strcpy() for something like this, ever.

Also, for newsgroups, don't use // comments because of wordwrapping
issues.

Gregory Pietsch

Nov 14 '05 #4

Eric Sosman wrote:
becte wrote:
I am little bit confused
Is this a legal way of removing a substring
from a string? What about the second alternative
using strcpy, is it ok even though the source and
dest. strings overlap?

// Remove (first occurence of) sub from src
void func(char *src, char *sub)
{
char *p;
if ((p=strstr(src,sub)) != NULL)
{
memmove(p,p+strlen(sub), strlen(p+strlen(sub))+1);


Looks all right to me.
// alternative
// strcpy(p,p+strlen(sub));


Undefined behavior if source and destination overlap
(i.e., if strlen(p+strlen(sub)) >= strlen(sub)).
}
}


That doesn't overlap. See
http://groups-beta.google.com/group/...8?dmode=source

imagine that you have, "aabbccdd"
and you search for the substring "dd"
then p points to the first "d" and
p + strlen(sub) would point one past the
second "d". This means a distinct value of
an object is used to assign to another
distinct object. Overlap does not mean
any two pointers pointing in the same
memory region. It is an overlap when
the objects within the memory region
are not distinct. Consider this:

strcpy(p + 3, p); p overlaps p + 3 here
the converse cannot be said for p+offset
overlapping p.

--
aegis

Nov 14 '05 #5


aegis wrote:
Eric Sosman wrote:
becte wrote:

I am little bit confused
Is this a legal way of removing a substring
from a string? What about the second alternative
using strcpy, is it ok even though the source and
dest. strings overlap?

// Remove (first occurence of) sub from src
void func(char *src, char *sub)
{
char *p;
if ((p=strstr(src,sub)) != NULL)
{
memmove(p,p+strlen(sub), strlen(p+strlen(sub))+1);


Looks all right to me.

// alternative
// strcpy(p,p+strlen(sub));


Undefined behavior if source and destination overlap
(i.e., if strlen(p+strlen(sub)) >= strlen(sub)).

}
}

That doesn't overlap. See
http://groups-beta.google.com/group/...8?dmode=source

imagine that you have, "aabbccdd"
and you search for the substring "dd"
then p points to the first "d" and
p + strlen(sub) would point one past the
second "d". This means a distinct value of
an object is used to assign to another
distinct object. Overlap does not mean
any two pointers pointing in the same
memory region. It is an overlap when
the objects within the memory region
are not distinct. Consider this:

strcpy(p + 3, p); p overlaps p + 3 here
the converse cannot be said for p+offset
overlapping p.


No, there is an overlap problem. For strcpy(), the Standard does
not define in what order the characters from the string(arg 2)
are copied to the character array(arg1). Among possiblities,
an implementor may copy from the beginning of the string to the
end terminating character, as in function Mystrcpy1 example below.
Another possibility is for the implementor to copy to the character
array from the string's terminating character to the beginning of the
string, as shown in the function Mystrcpy2 example below.

Now, take the string "aabbccdd", and, attempt to remove the
substring "cc". It the implementor made strcpy like the Mystrcpy1
example, you will get away with using the strcpy. But, if the
the implementation was similiar to function Mystrcpy2 then the
resulting string will be wrong, "aabb" instead of "aabbdd".

Run the following to see the effect.

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

char *Mystrcpy1(char *s, const char *cs);
char *Mystrcpy2(char *s, const char *cs);
void func1(char *src, char *sub);
void func2(char *src, char *sub);

int main(void)
{
char s[32], *substr = "cc";

Mystrcpy2(s,"aabbccdd");
printf("From the string: \"%s\"\n",s);
printf("We will attempt to remove substring \"%s\"\n",substr);
func1(s,substr);
printf("Using function Mystrcpy1. The result: \"%s\"\n\n",s);

Mystrcpy2(s,"aabbccdd");
printf("From the string: \"%s\"\n",s);
printf("We will attempt to remove substring \"%s\"\n",substr);
func2(s,substr);
printf("Using function Mystrcpy2. The result: \"%s\"\n",s);
return 0;
}

char *Mystrcpy1(char *s, const char *cs)
{ /* Copy from beginning of string cs to the end */
char *s1;
const char *cs1;

for(s1 = s,cs1 = cs; '\0' != (*s1 = *cs1); s1++,cs1++) ;
return s;
}

char *Mystrcpy2(char *s, const char *cs)
{ /* Copy from the end of string cs to the beginning */
const char *tmp;
size_t n = strlen(cs);

for(tmp = cs+n; ; tmp--,n--)
{
*(s+n) = *tmp;
if(!n) break;
}
return s;
}

void func1(char *src, char *sub)
{ /* Using function Mystrcpy1 */
char *p;

if ((p=strstr(src,sub)) != NULL)
Mystrcpy1(p,p+strlen(sub));
return;
}

void func2(char *src, char *sub)
{ /* Using function Mystrcpy2 */
char *p;

if ((p=strstr(src,sub)) != NULL)
Mystrcpy2(p,p+strlen(sub));
return;
}

--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #6
aegis wrote:
Eric Sosman wrote:
becte wrote:

I am little bit confused
Is this a legal way of removing a substring
from a string? What about the second alternative
using strcpy, is it ok even though the source and
dest. strings overlap?

// Remove (first occurence of) sub from src
void func(char *src, char *sub)
{
char *p;
if ((p=strstr(src,sub)) != NULL)
{
[...]
// alternative
// strcpy(p,p+strlen(sub));


Undefined behavior if source and destination overlap
(i.e., if strlen(p+strlen(sub)) >= strlen(sub)).


That doesn't overlap. See
http://groups-beta.google.com/group/...8?dmode=source

imagine that you have, "aabbccdd"
and you search for the substring "dd"
then p points to the first "d" and
p + strlen(sub) would point one past the
second "d". [...]


Then strlen(p+strlen(sub)) will be zero and
strlen(sub) will be two. 0 >= 2 yields "false."

--
Eric Sosman
es*****@acm-dot-org.invalid
Nov 14 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: rajarao | last post by:
hi I want to remove the content embedded in <script> and </script> tags submitted via text box. My java script should remove the content embedded between <script> and </script> tag. my current...
11
by: Darren Anderson | last post by:
I have a function that I've tried using in an if then statement and I've found that no matter how much reworking I do with the code, the expected result is incorrect. the code: If Not...
23
by: Peter Row | last post by:
Hi, I am currently working on a VB.NET project that has been going for quite a while. In the past it has been developed with a lot of compatibility VB6 functions and constants, e.g Left(),...
2
by: Patrick.O.Ige | last post by:
I have a file below 16_vir24CE.log How can i remove 16_ or 123_ I want to have "vir24CE.log" as my output file
2
by: ankit | last post by:
Hi All, I want to remove a substring from a string without any additional tabs/returns in the output string. Is there any method availaible or how can I do it. For the ease, I am giving an...
0
by: nhmark64 | last post by:
My PC was a completely screwed up mess. Nieither the unistall tool or the manual uninstall at http://msdn.microsoft.com/vstudio/support/uninstall/default.aspx worked. I also tried the VS...
5
by: tom.hepworth | last post by:
Hi I have a problem which I hope someone can help me with because I really don't even know where to start with it. I am using Access 2003. I have a delimited text file which contains about...
1
by: IsValidUN | last post by:
I am trying to spit a delimited string (e.g. val1;val2;va31...) I am able to parse if correctly except if puts an unwanted namespace into the result. (example below) How do I remove xmlns="" from...
1
by: Gene Kelley | last post by:
This has got to be an easy one, but I'm just not getting it. The following function (below) returns name=value pairs from URL queries (GET). All is working as expected, but I am trying to figure...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.