473,548 Members | 2,716 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Replacing a word in a string

Hi guys!

I like C because is fun. So, I wrote this function for the lcc-win32
standard library: strrepl.

I thought that with so many "C heads" around, maybe we could improve it
in a collective brainstorming session.

Let's discuss some C here, for a change :-)

Specs:
-----
Function: strrepl

Synopsis

#include <string.h>
char *strrepl(char *InputString, char *StringToFind,
char *Replacement, char *Output);
Description

The strrepl function replaces in InputString all occurrences of
StringToFind by Replacement, writing the modified contents into the
Output string. The original input string is not modified.

If the Output argument is NULL, strrepl will return the space that would
be needed (including the terminating zero) for the replacement.

If Replacement is NULL and Output is not NULL, all occurrences of
StringToFind will be erased.

Returns

The strrepl function returns the needed length for the replacements if
its Output argument is NULL. If not, it returns the number of
replacements done.

Code:
-----
#include <string.h>
int strrepl(char *InputString,ch ar *StringToFind,
char *StringToReplac e,char *output)
{
char *offset = NULL, *CurrentPointer = NULL;
int insertlen;
int findlen = strlen(StringTo Find);
int result = 0;

if (StringToReplac e)
insertlen = strlen(StringTo Replace);
else
insertlen = 0;
if (output) {
if (output != InputString)
memmove(output, InputString,str len(InputString )+1);
InputString = output;
}
else
result = strlen(InputStr ing)+1;

while (*InputString) {
offset = strstr(!offset? InputString:Cur rentPointer,Str ingToFind);
if (offset == NULL)
break;
CurrentPointer = (offset + (output ? insertlen : findlen));
if (output) {
strcpy (offset, (offset + findlen));
memmove (offset + insertlen,
offset, strlen (offset) + 1);
if (insertlen)
memcpy (offset, StringToReplace , insertlen);
result++;
}
else {
result -= findlen;
result += insertlen;
}
}
return result;
}

All kinds of comments are welcome, regarding the code, the interface
design, the documentation, etc etc.

jacob
Dec 6 '05 #1
35 5801


jacob navia wrote On 12/06/05 15:41,:

Synopsis

#include <string.h>
char *strrepl(char *InputString, char *StringToFind,
char *Replacement, char *Output);
[...]

Code:
-----
#include <string.h>
int strrepl(char *InputString,ch ar *StringToFind,
char *StringToReplac e,char *output)


A diagnostic is required if both the declaration
and the definition appear in the same translation unit.
(In C, anyhow. That other language you're fond of may
have different rules.)

--
Er*********@sun .com

Dec 6 '05 #2
jacob navia wrote:
Hi guys!

I like C because is fun. So, I wrote this function for the lcc-win32
standard library: strrepl.

I thought that with so many "C heads" around, maybe we could improve it
in a collective brainstorming session.

Let's discuss some C here, for a change :-)

Specs:
-----
Function: strrepl

Synopsis

#include <string.h>
char *strrepl(char *InputString, char *StringToFind, ^^^^^^
ITYM: int or size_t char *Replacement, char *Output);
In order to avoid name clashes, I'd rather call the function
str_repl or strRepl or replaceSubstrin g.
Description

The strrepl function replaces in InputString all occurrences of
StringToFind by Replacement, writing the modified contents into the
Output string. The original input string is not modified.
Then your prototype is wrong: You want
size_t str_repl(const char* restrict InputString,
const char* StringToFind,
const char* Replacement,
char* restrict Output);
to avoid this. Or do away with the restrict if you want
to express that the original string is not modified via
InputString.
If the Output argument is NULL, strrepl will return the space that would
be needed (including the terminating zero) for the replacement.

If Replacement is NULL and Output is not NULL, all occurrences of
StringToFind will be erased.

Returns

The strrepl function returns the needed length for the replacements if
its Output argument is NULL. If not, it returns the number of
replacements done.
I would rather like a size parameter as in snprintf() so you
can give the size of the storage output points to.
<snip: Code>
All kinds of comments are welcome, regarding the code, the interface
design, the documentation, etc etc.


- I would rather aim for a standard order of the parameters,
say leading
destination, size,
followed by either
1) replacestr, source, findstr
or
2) source, replacestr, findstr

1) has the advantage that all parameters which can have special
values are gathered to the start.

- I would rather return size_t as strlen() returns size_t

- I would not "overload" the return value semantics depending
on destination -- the user cannot detect errors this way.
I'd rather settle for returning the number of bytes needed for
the "fully replaced" destination string and returning 0 on
error.
If the number of replacements is needed, use an additional
size_t* parameter.

- give a str_n_repl variant allowing to restrict the number of
replacements.
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Dec 6 '05 #3
Eric Sosman <er*********@su n.com> writes:
jacob navia wrote On 12/06/05 15:41,:

#include <string.h>
char *strrepl(char *InputString, char *StringToFind,
char *Replacement, char *Output);

[...]

int strrepl(char *InputString,ch ar *StringToFind,
char *StringToReplac e,char *output)


A diagnostic is required if both the declaration
and the definition appear in the same translation unit.


What? Have you never heard of a "function prototype"? They've
been all the rage since 1989 or so. Even before that, function
declarations before definitions were, I believe, allowed.

The real problem here is the differing return types.
--
char a[]="\n .CJacehknorstu" ;int putchar(int);in t main(void){unsi gned long b[]
={0x67dffdff,0x 9aa9aa6a,0xa77f fda9,0x7da6aa6a ,0xa67f6aaa,0xa a9aa9f6,0x11f6} ,*p
=b,i=24;for(;p+ =!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)bre ak;else default:continu e;if(0)case 1:putchar(a[i&15]);break;}}}
Dec 6 '05 #4
Ben Pfaff wrote:
Eric Sosman <er*********@su n.com> writes:
jacob navia wrote On 12/06/05 15:41,:

#include <string.h>
char *strrepl(char *InputString, char *StringToFind,
char *Replacement, char *Output);

[...]

int strrepl(char *InputString,ch ar *StringToFind,
char *StringToReplac e,char *output)


A diagnostic is required if both the declaration
and the definition appear in the same translation unit.


What? Have you never heard of a "function prototype"? They've
been all the rage since 1989 or so. Even before that, function
declarations before definitions were, I believe, allowed.

The real problem here is the differing return types.


I think it is pretty safe to assume that he was referring to the
declaration and definition that the OP presented.

Robert Gamble

Dec 6 '05 #5
"Michael Mair" <Mi**********@i nvalid.invalid> wrote in message
news:3v******** *****@individua l.net...
jacob navia wrote:
If the Output argument is NULL, strrepl will return the space that would
be needed (including the terminating zero) for the replacement.

If Replacement is NULL and Output is not NULL, all occurrences of
StringToFind will be erased.

Returns

The strrepl function returns the needed length for the replacements if
its Output argument is NULL. If not, it returns the number of
replacements done.


I would rather like a size parameter as in snprintf() so you
can give the size of the storage output points to.


I think that wouldn't necessarily make things any better. As I imagine, you
would rarely know how much storage could be needed by the function in
advance without calling it first with NULL as the Output argument. Also, if
you knew that, for example, strlen(StringTo Find)>=strlen(R eplacement) then
passing the size of storage that Output points to is pointless (since you
know how much you need, you just allocate it and that's it). While I like
the overall idea, I find this size issue very inpractical and error prone (I
imagine this is one of the reasons something like this isn't in the standard
library in the first place - but there are probably many reasons far more
important than this). It might be better for str_repl to allocate the needed
space and return a pointer to it (with the proper output written to it
ofcourse).
Dec 6 '05 #6
jacob navia wrote:
char *strrepl(char *InputString, char *StringToFind,
char *Replacement, char *Output);


OOOOPS
That should have been:

int strrepl (...)
^^^
of course!

Excuse me for this error.
Dec 6 '05 #7
Robert Gamble wrote:


I think it is pretty safe to assume that he was referring to the
declaration and definition that the OP presented.

Robert Gamble


Yes, I think Eric was misled by a confusion in the declaration:
it is int strrepl, not char *strrepl, as I mistakenly wrote.

Excuse me for this error.
jacob
Dec 6 '05 #8
Michael Mair wrote:
jacob navia wrote:
Hi guys!

I like C because is fun. So, I wrote this function for the lcc-win32
standard library: strrepl.

I thought that with so many "C heads" around, maybe we could improve it
in a collective brainstorming session.

Let's discuss some C here, for a change :-)

Specs:
-----
Function: strrepl

Synopsis

#include <string.h>
char *strrepl(char *InputString, char *StringToFind,
^^^^^^
ITYM: int or size_t
char *Replacement, char *Output);

In order to avoid name clashes, I'd rather call the function
str_repl or strRepl or replaceSubstrin g.
Description

The strrepl function replaces in InputString all occurrences of
StringToFind by Replacement, writing the modified contents into the
Output string. The original input string is not modified.

Then your prototype is wrong: You want
size_t str_repl(const char* restrict InputString,
const char* StringToFind,
const char* Replacement,
char* restrict Output);
to avoid this. Or do away with the restrict if you want
to express that the original string is not modified via
InputString.
If the Output argument is NULL, strrepl will return the space that
would be needed (including the terminating zero) for the replacement.

If Replacement is NULL and Output is not NULL, all occurrences of
StringToFind will be erased.

Returns

The strrepl function returns the needed length for the replacements if
its Output argument is NULL. If not, it returns the number of
replacements done.

I would rather like a size parameter as in snprintf() so you
can give the size of the storage output points to.

<snip: Code>

All kinds of comments are welcome, regarding the code, the interface
design, the documentation, etc etc.

- I would rather aim for a standard order of the parameters,
say leading
destination, size,
followed by either
1) replacestr, source, findstr
or
2) source, replacestr, findstr

1) has the advantage that all parameters which can have special
values are gathered to the start.

- I would rather return size_t as strlen() returns size_t


Yes, this is a good remark.

- I would not "overload" the return value semantics depending
on destination -- the user cannot detect errors this way.
I'd rather settle for returning the number of bytes needed for
the "fully replaced" destination string and returning 0 on
error.
Yes, but how would the user know how much to allocate?
The problem is that the user can't know how long the result string
will be.
If the number of replacements is needed, use an additional
size_t* parameter.
I think the number of replacements is only useful for knowing
if there was any replaceements at all, i.e; != 0

- give a str_n_repl variant allowing to restrict the number of
replacements.
Cheers
Michael


Thanks for your input.
Dec 6 '05 #9
jacob navia wrote:
Michael Mair wrote:
jacob navia wrote:
<snip string replacement function>
- I would not "overload" the return value semantics depending
on destination -- the user cannot detect errors this way.
I'd rather settle for returning the number of bytes needed for
the "fully replaced" destination string and returning 0 on
error.


Yes, but how would the user know how much to allocate?
The problem is that the user can't know how long the result string
will be.


The user can always know the upper bound by knowing the length of the
input string, length of search string and length of replacement string
then assuming if the replacement is longer than the search that the
input string consists entirely of strings to be replaced.
If the number of replacements is needed, use an additional
size_t* parameter.


I think the number of replacements is only useful for knowing
if there was any replaceements at all, i.e; != 0


A counter example: implementing a text editor doing a search and replace
that tells the user how many instances have been replaced. I've used
such text editors and it is a nice thing to see.

I agree with Michael that the string length and count of items replaced
should be seperate returned values.
- give a str_n_repl variant allowing to restrict the number of
replacements.


The main use I see for that is to replace only the first instance.

I think being able to specify the buffer size would be good.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Dec 7 '05 #10

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

Similar topics

3
5713
by: dumbledad | last post by:
Hi All, I'm confused by how to replace a SELECT statement in a SQL statement with a specific value. The table I'm working on is a list of words (a column called "word") with an index int pointing to the sentence they come from (a column called "regret"). I also have a table of stop words (called "GenericStopWords") that contains the words I...
2
3387
by: Christopher Beltran | last post by:
I am currently trying to replace certain strings, not single characters, with other strings inside a word document which is then sent to a browser as a binary file. Right now, I read in the word file, convert the FileStream into a string using Unicode encoding, then do a replace, then convert the string back to a byte using Unicode encoding...
0
1324
by: leeonions | last post by:
Hi there, i am trying to use regular expressions to search through a text string and replace a given whole word. take the string = "The matsat on the mat!" (bad example i know) i want to replace the whole word 'mat' with the word 'cat' to give "The matsat on the cat!" (matsat was not replaced as only whole word match, cat on the other
2
11098
by: leeonions | last post by:
Hi there, i am trying to use regular expressions to search through a text string and replace a given whole word. take the string = "The matsat on the mat!" (bad example i know) i want to replace the whole word 'mat' with the word 'cat' to give "The matsat on the cat!" (matsat was not replaced as only whole word match, cat on the other
0
1412
by: Lakhi | last post by:
hi frnds, I need small help in String replacement I need to replace the text using replceAll() with Case-Insensitve . Is there any regular expression for this? i have this expression s.replaceAll("(?i)\\bjava"\\b","xxxx"); it is replacing the all the words like Java,jAva,jaVA .....
7
3501
by: aine_canby | last post by:
Hi, Im totally new to Python so please bare with me. Data is entered into my program using the folling code - str = raw_input(command) words = str.split() for word in words:
1
12152
by: jonnyboy6969 | last post by:
Hi All Really hoping someone can help me out here with my deficient regex skills :) I have a function which takes a string of HTML and replaces a term (word or phrase) with a link. The pupose is that I seek out terms which are in a glossary on our site, and automatically link to this definition. Its slightly complex becase certain elements...
4
2784
by: sandvet03 | last post by:
I am trying to expand on a earlier program for counting subs and now i am trying to replace substrings within a given string. For example if the main string was "The cat in the hat" i am trying to find a chosen substring lets say "cat" and then replace it with a difrent inputed substring say "dog". Tried to get as far as i could on my own but...
1
7829
by: =?ISO-8859-1?Q?S=F8ren?= | last post by:
Hi guys I got the following code: ------------------------------------------------------- Dim Word As New Microsoft.Office.Interop.Word.Application Dim Document As Microsoft.Office.Interop.Word.Document Document = Word.Documents.Open(Filename)
0
7518
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7444
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7711
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
7954
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
7805
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
5085
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3497
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3478
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1054
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.